simpleXMLElement remove by yourself encoding - php

I need to create an XML in PHP.
My code start with:
$doc = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><iv:Fornitura xmlns:cm="urn:www.agenziaentrate.gov.it:specificheTecniche:common" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:tm="urn:www.agenziaentrate.gov.it:specificheTecniche:telent:v1" xmlns:iv="urn:www.agenziaentrate.gov.it:specificheTecniche:sco:ivp"></iv:Fornitura>', LIBXML_NOERROR, false, 'iv', true);
$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom_xml = dom_import_simplexml($doc);
$dom_xml = $dom->importNode($dom_xml, true);
$dom_xml = $dom->appendChild($dom_xml);
$file_XML = $dom->saveXML(); // SAVE TO STRING
Expected result:
<?xml version="1.0" encoding="UTF-8"?>
<iv:Fornitura xmlns:cm="urn:www.agenziaentrate.gov.it:specificheTecniche:common" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:iv="urn:www.agenziaentrate.gov.it:specificheTecniche:sco:ivp">
</iv:Fornitura>
But I always get:
<?xml version="1.0"?>
<iv:Fornitura xmlns:cm="urn:www.agenziaentrate.gov.it:specificheTecniche:common" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:iv="urn:www.agenziaentrate.gov.it:specificheTecniche:sco:ivp">
</iv:Fornitura>
It seem encoding encoding="UTF-8" disappear. Using also addAttribute doesn't work.

Rather than disappearing, I'd say it never gets added in the first place:
$dom = new DOMDocument('1.0');
As per docs:
public DOMDocument::__construct ([ string $version [, string $encoding ]] )`
Demo

Related

XML PHP Format Setup

Is there a why to do this? I'm new on create DomDocument. Thank you
<!DOCTYPE Data SYSTEM "http://data.data.org/schemas/data/1.234.1/data.dtd"> <Data payloadID = "123123123131231232323" timestamp = "2015-06-10T12:59:09-07:00">
$aribaXML = new DOMImplementation;
$dtd = $aribaXML->createDocumentType('cXML', '', 'http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd');
$dom = $aribaXML->createDocument('', '', $dtd);
Here are two ways in DOM to create a new document in PHP. If you don't need the DTD you can directly create an instance of the DOMDocument class.
$document = new DOMDocument('1.0', "UTF-8");
$document->appendChild(
$cXML = $document->createElement('cXML')
);
echo $document->saveXML();
Output:
<?xml version="1.0" encoding="UTF-8"?>
<cXML/>
For a document with a DTD your approach was correct.
$implementation = new DOMImplementation;
$dtd = $implementation->createDocumentType(
'cXML', '', 'http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd'
);
$document = $implementation->createDocument("", "cXML", $dtd);
$document->encoding = 'UTF-8';
$cXML = $document->documentElement;
echo $document->saveXML();
Output:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd">
After the initial bootstrap you use methods of the $document to create nodes and append them.
// set an attribute on the document element
$cXML->setAttribute('version', '1.1.007');
// xml:lang is a namespaced attribute in a reserved namespace
$cXML->setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:lang', 'en-US');
// nested elements
// create a node, store it for the next call and append it
$cXML->appendChild(
$header = $document->createElement('Header')
);
$header->appendChild(
$from = $document->createElement('From')
);
$from->appendChild(
$credential = $document->createElement('Credential')
);
// "Identity" has only a text node so we don't need to store it for later
$credential->appendChild(
$document->createElement('Identity')
)->textContent = '83528721';
// format serialized XML string
$document->formatOutput = TRUE;
echo $document->saveXML();
Output:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd">
<cXML version="1.1.007" xml:lang="en-US">
<Header>
<From>
<Credential>
<Identity>83528721</Identity>
</Credential>
</From>
</Header>
</cXML>
$xml = new DomDocument('1.0');
$xml->formatOutput = true;
$works = $xml->createElement("works");
$xml->appendChild($works);
$work = $xml->createElement("work");
$work->setAttribute("id",1);
$works->appendChild($work);
$xml->save("storage/document.xml") or die("Error, Unable to create XML File");

Duplicate xml namespace declarations php DOMDocument

I use PHP DOMDocument to generate xml. Sometimes namespaces are declared only on root element, which is intended behaviour, but sometimes no.
For example:
$xml = new DOMDocument('1.0', 'utf-8');
$ns = "http://ns.com";
$otherNs = "http://otherns.com";
$docs = $xml->createElementNS($ns, "ns:Documents");
$doc = $xml->createElementNS($otherNs, "ons:Document");
$innerElement = $xml->createElementNS($otherNs, "ons:innerElement", "someValue");
$doc->appendChild($innerElement);
$docs->appendChild($doc);
$xml->appendChild($docs);
$xml->formatOutput = true;
$xml->save("dom");
I expect:
<?xml version="1.0" encoding="UTF-8"?>
<ns:Documents xmlns:ns="http://ns.com" xmlns:ons="http://otherns.com">
<ons:Document>
<ons:innerElement>someValue</ons:innerElement>
</ons:Document>
</ns:Documents>
But got:
<?xml version="1.0" encoding="UTF-8"?>
<ns:Documents xmlns:ns="http://ns.com" xmlns:ons="http://otherns.com">
<ons:Document xmlns:ons="http://otherns.com">
<ons:innerElement>someValue</ons:innerElement>
</ons:Document>
</ns:Documents>
Why declaration of xmlns:ons="http://otherns.com" appears on Document element, but not in <innerElement>? And how to prevent duplicates?
It's very easy. Just add your nodes into document tree.
Additionally you can explicitly create xmlns:XXX atrtribute in root node.
See example:
namespace test;
use DOMDocument;
$xml = new DOMDocument("1.0", "UTF-8");
$ns = "http://ns.com";
$otherNs = "http://otherns.com";
$docs = $xml->createElementNS($ns, "ns:Documents");
$xml->appendChild($docs);
$docs->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:ons', $otherNs);
$doc = $xml->createElement("ons:Document");
$docs->appendChild($doc);
$innerElement = $xml->createElement("ons:innerElement", "someValue");
$doc->appendChild($innerElement);
$xml->formatOutput = true;
echo $xml->saveXML();
Result:
<?xml version="1.0" encoding="UTF-8"?>
<ns:Documents xmlns:ns="http://ns.com" xmlns:ons="http://otherns.com">
<ons:Document>
<ons:innerElement>someValue</ons:innerElement>
</ons:Document>
</ns:Documents>

Creating PHP -> XML with special character '&'

I'm trying to create an XML from PHP with special characters.
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8" ' . 'standalone="yes"?><Root/>');
$data->addChild('NAME', $variable);
$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xmlAusgabe = $xml->asXML());
$dom->save('../test.xml');
When there is a special character like '&' in it the output is empty.
I thought these characters are available in UTF-8.
Can someone help me?
When embed XML, always there are many problems :( try this:
Change
$dom->loadXML($xmlAusgabe = $xml->asXML());
by
$xmlAusgabe = $xml->asXML();
$xmlAusgabe = mb_convert_encoding( $xmlAusgabe, 'HTML-ENTITIES', 'UTF-8') ;
$dom->loadXML( $xmlAusgabe );
Then check encoding and fileencoding is utf8. If you use vim editor:
set encoding=utf-8
set fileencoding=utf-8
UPDATE
libxml_use_internal_errors( FALSE );
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Root/>');
$data->addChild('NAME', mb_convert_encoding( $variable, 'HTML-ENTITIES', 'UTF-8') );
$xmlAusgabe = $xml->asXML();
$dom = new DOMDocument();
$dom->loadXML( $xmlAusgabe );
$dom->save('../test.xml');
I check this code and run. To print error use:
libxml_get_errors()

Append QBXML declaration in XML with DOMDocument

Trying to write clean XML for a QuickBooks integration using DOMDocument in PHP. The only thing I am stuck on is how to add the required <?qbxml version="2.0"?> after <?xml version="1.0" encoding="utf-8"?> to produce the following:
<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="2.0"?>
.....
Here is what I have so far..
$dom = new DOMDocument('1.0', 'utf-8');
//Need to somehow add qbxml version here
$qbxml = $dom->appendChild($dom->createElement('QBXML'));
$qbxmlmsg = $qbxml->appendChild($dom->createElement('QBXMLMsgsRq'));
$qbxmlmsg->setAttribute('onError', 'stopOnError');
$salesReceiptAddRq = $qbxmlmsg->appendChild($dom->createElement('SalesReceiptAddRq'));
$salesReceiptAddRq->setAttribute('requestID', 1234);
$dom->formatOutput = true;
echo $dom->saveXML();
That node is called a processing instruction.
$dom = new DOMDocument('1.0', 'utf-8');
$dom->appendChild($dom->createProcessingInstruction('qbxml', 'version="2.0"'));
$qbxml = $dom->appendChild($dom->createElement('QBXML'));
// ...
echo $dom->saveXml();

Missing formatting after adding childnode?

I'm trying to add a childnode in an XML document with PHP and got it OK so far except one thing. Can't get it formatted correct?
Here is the script:
$xmldoc = new DOMDocument();
$xml->formatOutput = true;
$xml->preserveWhiteSpace = false;
$xmldoc->loadXML('<?xml version="1.0" encoding="ISO-8859-1"?>
<data>
<udate>1347730639</udate>
<userid>3</userid>
</data>');
echo "<xmp>OLD:\n". $xmldoc->saveXML() ."</xmp>";
$root = $xmldoc->firstChild;
$newElement = $xmldoc->createElement('popup');
$root->appendChild($newElement);
$newText = $xmldoc->createTextNode("0");
$newElement->appendChild($newText);
echo "<xmp>NEW:\n". $xmldoc->saveXML() ."</xmp>";
After adding the node I get this:
<data>
<udate>1347730639</udate>
<userid>3</userid>
<popup>0</popup></data>
I want it to be like this:
<data>
<udate>1347730639</udate>
<userid>3</userid>
<popup>0</popup>
</data>
Where do I go wrong?
Please help and thanks in advance :-)
createElement will break formatOutput this is a general issue
See PHP BUG Report
formatOutput does not work with saveHTML
DOMDocument->formatOutput = true does not work
But you can have a work around by reloading and formatting it.
$xmldoc = new DOMDocument();
$xmldoc->loadXML('<?xml version="1.0" encoding="ISO-8859-1"?>
<data>
<udate>1347730639</udate>
<userid>3</userid>
</data>');
echo "<xmp>OLD:\n". $xmldoc->saveXML() ."</xmp>";
$root = $xmldoc->firstChild;
$newElement = $xmldoc->createElement('popup');
$root->appendChild($newElement);
$newText = $xmldoc->createTextNode("0");
$newElement->appendChild($newText);
$xml = new DOMDocument();
$xml->preserveWhiteSpace = false;
$xml->formatOutput = true;
$xml->loadXML( $xmldoc->saveXML());
echo "<xmp>NEW:\n". $xml->saveXML()."</xmp>";
Output
OLD:
<?xml version="1.0" encoding="ISO-8859-1"?>
<data>
<udate>1347730639</udate>
<userid>3</userid>
</data>
NEW:
<?xml version="1.0" encoding="ISO-8859-1"?>
<data>
<udate>1347730639</udate>
<userid>3</userid>
<popup>0</popup>
</data>
You might want to try removing all whitespace before and then formatting.
force it to remake the xml from scratch.
$xml->preserveWhiteSpace = false;
$xml->formatOutput = true;

Categories