Here are the codes:
$doc = new DomDocument('1.0');
// create root node
$root = $doc->createElement('root');
$root = $doc->appendChild($root);
$signed_values = array('a' => 'eee', 'b' => 'sd', 'c' => 'df');
// process one row at a time
foreach ($signed_values as $key => $val) {
// add node for each row
$occ = $doc->createElement('error');
$occ = $root->appendChild($occ);
// add a child node for each field
foreach ($signed_values as $fieldname => $fieldvalue) {
$child = $doc->createElement($fieldname);
$child = $occ->appendChild($child);
$value = $doc->createTextNode($fieldvalue);
$value = $child->appendChild($value);
}
}
// get completed xml document
$xml_string = $doc->saveXML() ;
echo $xml_string;
If I print it in the browser I don't get nice XML structure like
<xml> \n tab <child> etc.
I just get
<xml><child>ee</child></xml>
And I want to be utf-8
How is this all possible to do?
You can try to do this:
...
// get completed xml document
$doc->preserveWhiteSpace = false;
$doc->formatOutput = true;
$xml_string = $doc->saveXML();
echo $xml_string;
You can make set these parameter right after you've created the DOMDocument as well:
$doc = new DomDocument('1.0');
$doc->preserveWhiteSpace = false;
$doc->formatOutput = true;
That's probably more concise. Output in both cases is (Demo):
<?xml version="1.0"?>
<root>
<error>
<a>eee</a>
<b>sd</b>
<c>df</c>
</error>
<error>
<a>eee</a>
<b>sd</b>
<c>df</c>
</error>
<error>
<a>eee</a>
<b>sd</b>
<c>df</c>
</error>
</root>
I'm not aware how to change the indentation character(s) with DOMDocument. You could post-process the XML with a line-by-line regular-expression based replacing (e.g. with preg_replace):
$xml_string = preg_replace('/(?:^|\G) /um', "\t", $xml_string);
Alternatively, there is the tidy extension with tidy_repair_string which can pretty print XML data as well. It's possible to specify indentation levels with it, however tidy will never output tabs.
tidy_repair_string($xml_string, ['input-xml'=> 1, 'indent' => 1, 'wrap' => 0]);
With a SimpleXml object, you can simply
$domxml = new DOMDocument('1.0');
$domxml->preserveWhiteSpace = false;
$domxml->formatOutput = true;
/* #var $xml SimpleXMLElement */
$domxml->loadXML($xml->asXML());
$domxml->save($newfile);
$xml is your simplexml object
So then you simpleXml can be saved as a new file specified by $newfile
<?php
$xml = $argv[1];
$dom = new DOMDocument();
// Initial block (must before load xml string)
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
// End initial block
$dom->loadXML($xml);
$out = $dom->saveXML();
print_R($out);
Tried all the answers but none worked. Maybe it's because I'm appending and removing childs before saving the XML.
After a lot of googling found this comment in the php documentation. I only had to reload the resulting XML to make it work.
$outXML = $xml->saveXML();
$xml = new DOMDocument();
$xml->preserveWhiteSpace = false;
$xml->formatOutput = true;
$xml->loadXML($outXML);
$outXML = $xml->saveXML();
// ##### IN SUMMARY #####
$xmlFilepath = 'test.xml';
echoFormattedXML($xmlFilepath);
/*
* echo xml in source format
*/
function echoFormattedXML($xmlFilepath) {
header('Content-Type: text/xml'); // to show source, not execute the xml
echo formatXML($xmlFilepath); // format the xml to make it readable
} // echoFormattedXML
/*
* format xml so it can be easily read but will use more disk space
*/
function formatXML($xmlFilepath) {
$loadxml = simplexml_load_file($xmlFilepath);
$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($loadxml->asXML());
$formatxml = new SimpleXMLElement($dom->saveXML());
//$formatxml->saveXML("testF.xml"); // save as file
return $formatxml->saveXML();
} // formatXML
Two different issues here:
Set the formatOutput and preserveWhiteSpace attributes to TRUE to generate formatted XML:
$doc->formatOutput = TRUE;
$doc->preserveWhiteSpace = TRUE;
Many web browsers (namely Internet Explorer and Firefox) format XML when they display it. Use either the View Source feature or a regular text editor to inspect the output.
See also xmlEncoding and encoding.
This is a slight variation of the above theme but I'm putting here in case others hit this and cannot make sense of it ...as I did.
When using saveXML(), preserveWhiteSpace in the target DOMdocument does not apply to imported nodes (as at PHP 5.6).
Consider the following code:
$dom = new DOMDocument(); //create a document
$dom->preserveWhiteSpace = false; //disable whitespace preservation
$dom->formatOutput = true; //pretty print output
$documentElement = $dom->createElement("Entry"); //create a node
$dom->appendChild ($documentElement); //append it
$message = new DOMDocument(); //create another document
$message->loadXML($messageXMLtext); //populate the new document from XML text
$node=$dom->importNode($message->documentElement,true); //import the new document content to a new node in the original document
$documentElement->appendChild($node); //append the new node to the document Element
$dom->saveXML($dom->documentElement); //print the original document
In this context, the $dom->saveXML(); statement will NOT pretty print the content imported from $message, but content originally in $dom will be pretty printed.
In order to achieve pretty printing for the entire $dom document, the line:
$message->preserveWhiteSpace = false;
must be included after the $message = new DOMDocument(); line - ie. the document/s from which the nodes are imported must also have preserveWhiteSpace = false.
based on the answer by #heavenevil
This function pretty prints using the browser
function prettyPrintXmlToBrowser(SimpleXMLElement $xml)
{
$domXml = new DOMDocument('1.0');
$domXml->preserveWhiteSpace = false;
$domXml->formatOutput = true;
$domXml->loadXML($xml->asXML());
$xmlString = $domXml->saveXML();
echo nl2br(str_replace(' ', ' ', htmlspecialchars($xmlString)));
}
Related
how to add xml node <TypeId>HDU5K3KDI23F</TypeId> to the 'Top' node of the XML variable before saving.
XML data i am getting is coming from API as a Response.
When i use the below code,xml response data does get saved, but the 'Typeid' Node is not getting saved in that file.
XML Response Data looks like this
<GetCategories>
<GetProduct>
<Data>
<Id>87772873</Id>
<Name>Foods and Beverages</Name>
<Top>
<CategoryId>028392323</CategoryId>
<CategoryName>Categories</CategoryName>
</Top>
</Data>
</GetProduct>
</GetCategories>
Code
$dom = new DOMDocument;
$dom->loadXML($response->toXML());
$dom->preserveWhiteSpace = FALSE;
$Xpath = new DOMXpath($dom);
foreach ($Xpath->evaluate('/GetCategories/GetProduct/Data/Top[1]') as $data)
{
$type = $data->appendChild($dom->createElement('TypeId'));
$type->appendChild($dom->createTextNode('HDU5K3KDI23F'));
}
$dom->formatOutput = TRUE;
$xmldata = $dom->saveXML();
echo $xmldata;
$myfile = file_put_contents('data.xml', $xmldata.PHP_EOL , FILE_APPEND | LOCK_EX);
Change the code in foreach as follows:
First create element with value and append to your data.
foreach ($Xpath->evaluate('/GetCategories/GetProduct/Data/Top[1]') as $data)
{
$type = $dom->createElement('TypeId', 'HDU5K3KDI23F');
$data->appendChild($type);
}
i have a xml file, when i have load this file using DOMDocument:: load and save it gives white space, please suggest how to remove this white space. Below is my code.
$file = 'myfile.xml'
$doc = new DOMDocument('1.0', 'utf-8');
$doc->preserveWhiteSpace = false;
$doc->load($file);
echo htmlentities($doc->saveXML());exit;
It give output like this
<?xml version="1.0"?> <Esign ver="2.0"></Esign>
how to remove this space
Actually i am trying to perform digital signature
below is my function for digital signature, In this function i found that space added after $doc->load($file)
public function digital_sign($file){
$doc = new DOMDocument('1.0', 'utf-8');
$doc->preserveWhiteSpace = false;
$doc->load($file);
// Create a new Security object
$objDSig = new XMLSecurityDSig();
// Use the c14n exclusive canonicalization
$objDSig->setCanonicalMethod(XMLSecurityDSig::C14N_COMMENTS);
// Sign using SHA-256
$objDSig->addReference($doc,XMLSecurityDSig::SHA256,array('http://www.w3.org/2000/09/xmldsig#enveloped-signature'),array('force_uri'=>'true'));
// Create a new (private) Security key
$objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, array('type'=>'private'));
// Load the private key
$objKey->loadKey('private_key.pem', TRUE);
$objDSig->sign($objKey);
// Add the associated public key to the signature
$options['subjectName'] = "true";
$objDSig->add509Cert(file_get_contents('public_key.cer'),true,false,$options);
// Append the signature to the XML
$objDSig->appendSignature($doc->documentElement);
$filenewpath = 'newfile1.xml';
ob_clean();
if($doc->save($filenewpath)){
return true;
}
}
$file contain below xml
<Esign ver="2.0" sc="Y" ts="2018-03-30T07:10:47" txn="97051198" ekycMode="U" ekycId="88XXXXXXXXX" ekycIdType="A" aspId="ASPSXXXXXXXXXXX156" AuthMode="1" responseSigType="pkcs7" preVerified="n" organizationFlag="n" responseUrl="https://www.google.com"><Docs><InputHash id="1" hashAlgorithm="SHA256" docInfo="Test pdf">60bdd13ea4827b8de375c79dc3ff847f83b55bd73b6461523fdf8f843b5a0d5b</InputHash></Docs></Esign>
Output After signature
<?xml version="1.0"?> <Esign ver="2.0" sc="Y" ts="2018-03-30T07:21:03" txn="39242002" ekycMode="U" ekycId="88XXXXXXXXX" ekycIdType="A" aspId="ASPSXXXXXXXXXXX156" AuthMode="1" responseSigType="pkcs7" preVerified="n" organizationFlag="n" responseUrl="https://www.stage.kissht.com/welcome/email"><Docs><InputHash id="1" hashAlgorithm="SHA256" docInfo="Test pdf">60bdd13ea4827b8de375c79dc3ff847f83b55bd73b6461523fdf8f843b5a0d5b</InputHash></Docs><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><DigestValue>bstOvGSSvkuEcriLXk6Qj2nhzEb3BZ1oEUtOYoMFyCw=</DigestValue></Reference></SignedInfo><SignatureValue>Uj3aSvmbMhUJX5Bwj3Bk3/F5U6IFx4LMS1BWMLTeEtnMvcfrJo25YGZHQtt1CnPbT5ygKEU7dQ3IBRsghqDvG+VAHYbU9gfX1N/5NxLM15oGWhZ3oSlNv7ouS1Ajzvaiei/OTr83jlUVfTW/MftYo/z6wYFdZp6Gc+0Fp38RLTzYPLr0l34NN/dIBy5/+FDYc9yTJrkwqj4SEQelmt0mzbV2jMo1/Nbvf+BLJq4+QMBoqjCiAlqcqc2/xX6K1xlUrPRwy6FC7ymFMBth0+9HJ6KLIwO+8Q+iUZgj3YFQdry1YGVDF1YNSTo5YcJcqrXycLFjTK2PDFcJ4rJg56IaXA==</SignatureValue><KeyInfo><X509Data><X509SubjectName>CN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</X509SubjectName><X509Certificate>MIIGCDCCBPCgAwIBAgIEANFsFzANBgkqhkiG9w0BAQsFADCBkzELMAkGA1UEBhMCSU4xKjAoBgNVBAoTIWVNdWRocmEgQ29uc3VtZXIgU2VydmljZXMgTGltaXRlZDEdMBsGA1UECxMUQ2VydGlmeWluZyBBdXRob3JpdHkxOTA3BgNVBAMTMGUtTXVkaHJhIFN1YiBDQSBDbGFzcyAyIGZvciBEb2N1bWVudCBTaWduZXIgMjAxNDAeFw0xNzAyMjEwOTMwMjhaFw0xOTAyMjEwOTMwMjhaMIHwMQswCQYDVQQGEwJJTjEyMDAGA1UEChMpU0kgQ1JFVkEgQ0FQSVRBTCBTRVJWSUNFUyBQUklWQVRFIExJTUlURUQxCzAJBgNVBAsTAklUMQ8wDQYDVQQREwY0MDAwMTIxFDASBgNVBAgTC01BSEFSQVNIVFJBMQ8wDQYDVQQJEwZNVU1CQUkxNzA1BgNVBDMTLjIwMiAyMDMgUEVOSU5TVUxBIENFTlRSRSBEUiBTIFMgUkFPIFJPQUQgUEFSRUwxLzAtBgNVBAMTJkRTIFNJIENSRVZBIENBUElUQUwgU0VSVklDRVMgUFJJVkFURSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsi9KF+7r6qBvsM27zlyYqQHXw867koX3CNNw4onRPSoxFEv1yThaYSA5MUFp5OQlq7/wKWWhKh842BVRJ7ov7iLSUXHSEmvbw70czribN3Ps9xXnOeHT+REchBeshttjdaZ7NTMyITVPcL6rzZ3Z8FT1ce9vtl4akls9ghXRRBTatzP/QKztLcxyB7RkGXV+tESeAhPqnP9RsHbGLRCQdIo9yEc4nJxDvuItxdTs/BcUTLpxeYaUlYYhXAeMWmHMsm5EtGH6eTyG3kWyaFyQF2aMdwGALxaHHie/OtLWm5w1tecOfpymO6uhlC6dfzhQTBwgHJGw/8P+wSK7gQnQbfG3zSQiGJn2vjy9sHTbmJoLcOc5ZhyhaWSMymTepXKwXpI</X509Certificate></X509Data></KeyInfo></Signature></Esign>
how to remove this space
<?xml version="1.0"?> <Esign
The saveXML() function creates a line-break after the <?xml ?> tag. Displayed in HTML environment, you see a "space".
You can use str_replace() to remove this "\n" before to use htmlentities() for this specific case:
$file = 'myfile.xml';
$doc = new DOMDocument('1.0', 'utf-8');
$doc->preserveWhiteSpace = false;
$doc->load($file);
$xml = $doc->saveXML();
$xml = str_replace("?>\n<", '?><', $xml);
// $xml = str_replace("?>".PHP_EOL."<", '?><', $xml);
// $xml = preg_replace("~\?>\s+<~", '?><', $xml);
echo htmlentities($xml);
exit;
Will outputs:
<?xml version="1.0"?><Esign ver="2.0"></Esign>
Im trying to create a XML file using php.
When I print my xml it prints it all in one line and not in proper format.
$xml = new DomDocument();
**$xml->preserveWhiteSpace = false;
$xml->FormatOutput = true;**
$parent = $xml->createElement("foo");
$parent->setAttribute("xmlns", "http://");
$parent->setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
$parent->setAttribute("xsi:schemaLocation", "link");
$xml->appendChild($parent);
$child = $xml->createElement("foo1");
$parent->appendChild($child);
$subchile = $xml->createElement($foo);
$child->appendChild($subchile);
$s_c = $xml->createElement("foo3",$foo3);
$subchile->appendChild($s_c);
echo "<xmp>" . $xml->saveXML() . "<xml>";
$xml->save($file_name)
it prints everything without indentations etc.
I read other questions here and followed the answers but still nothing. Can you help?
changed $xml->FormatOutput = true; ---> $xml->formatOutput = true;
I have a question: I am trying to create a XML file using DomDocument and I would like to have this output:
<?xml version="1.0" encoding="UTF-8"?>
<winstrom version="1.0">
<main_tag>
<child_tag>example</child_tag>
</main_tag>
<winstrom>
The problem is with the second row - if I write it as below then the output is "Invalid Character Error". I guess it is not allowed to have space characters there... However I need it like this, so what are the options?
$dom = new DomDocument('1.0', 'UTF-8');
$root = $dom->createElement('winstrom version=1.0');
$dom->appendChild($root);
$item = $dom->createElement('hlavni_tag');
$root2->appendChild($item);
$text = $dom->createTextNode('example');
$item->appendChild($text);
$dom->formatOutput = true;
echo $dom->saveXML();
There seems to be a misunderstanding of what an XML element is and how it differs from attributes.
Try this code:
<?php
$dom = new DomDocument('1.0', 'UTF-8');
$root = $dom->createElement('winstrom');
$root->setAttribute("version","1.0");
$dom->appendChild($root);
$root2 = $dom->createElement("main_tag"); //You forgot this part
$root->appendChild($root2);
$item = $dom->createElement('hlavni_tag'); //Should it be "child_tag"?
$root2->appendChild($item);
$text = $dom->createTextNode('example');
$item->appendChild($text);
$dom->formatOutput = true;
echo $dom->saveXML();
I have the following code in my PHP script:
$str = '<item></item>';
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->formatOutput = true;
$xml->load('file.xml');
$items = $addon->getElementsByTagName('items')->item(0);
$items->nodeValue = $str;
$xml->save('file.xml');
In the saved file.xml I see the following:
<item><\item>
How can I save it in the XML file without encoding HTML entities?
Use a DOMDocumentFragment:
<?php
$doc = new DOMDocument();
$doc->load('file.xml'); // '<doc><items/></doc>'
$item = $doc->createDocumentFragment();
$item->appendXML('<item id="1">item</item>');
$doc->getElementsByTagName('items')->item(0)->appendChild($item);
$doc->save('file.xml');
If you're appending to the root element, use $doc->documentElement->appendChild($item); instead of getElementsByTagName.