PHP Simplexml How to Save the File in a Formatted Way

How to save changed SimpleXML object back to file?

Not sure I understand the issue. The asXML() method accepts an optional filename as param that will save the current structure as XML to a file. So once you have updated your XML with the hints, just save it back to file.

// Load XML with SimpleXml from string
$root = simplexml_load_string('<root><a>foo</a></root>');
// Modify a node
$root->a = 'bar';
// Saving the whole modified XML to a new filename
$root->asXml('updated.xml');
// Save only the modified node
$root->a->asXml('only-a.xml');

Format output of $SimpleXML->asXML();

There's a variety of solutions in the comments on the PHP manual page for SimpleXMLElement. Not very efficient, but certainly terse, is a solution by Anonymous

$dom = dom_import_simplexml($simpleXml)->ownerDocument;
$dom->formatOutput = true;
echo $dom->saveXML();

The PHP manual page comments are often good sources for common needs, as long as you filter out the patently wrong stuff first.

Prettifying/Formatting output in SimpleXML

AFAIK simpleXML can't do it on its own.

However, DOMDocument can.

$dom = dom_import_simplexml($sxe)->ownerDocument;
$dom->formatOutput = TRUE;
$formatted = $dom->saveXML();

How to save a neatly formatted XML file using Simple XML?

If the proper format of Xml is important for you instead of SimpleXml use the DOM (also included and much more complex) extension that has a property for this:

$xml->formatOutput = true;

SimpleXMLElement won't save readable well-formatted file

Found better solution using DOMDocument. Heres rewrited example of code inside the loop:

            $node_ad = $xml->CreateElement('ad');
$node_ads->appendChild($node_ad);

//$node_ads->addChild('title', htmlentities(htmlspecialchars(substr($resources['titles'][$i], 0, 70))));
$title = $xml->CreateElement('title', htmlentities(htmlspecialchars(substr($resources['titles'][$i], 0, 70))));
$node_ad->appendChild($title);

$text = $xml->CreateElement('text', 'Текст текст');
$node_ad->appendChild($text);

$images_node = $xml->CreateElement('images');
$node_ad->appendChild($images_node);

$images = $xml->CreateElement('image', $this->_mainUrl.'/uploads/'.$resources['images'][$i]);
$images_node->appendChild($images);

xml formatting- simple xml does not do pretty formatting (indent formatting)

First of all you were successful in finding out that DOMDocument supports formatted XML while SimpleXMLElement does not. And that is totally correct.

So as you want to use SimpleXMLElement to actually create the XML document but you also want to benefit from the formatting options from DOMDocument you might want to learn about the fact that both libraries are sister-libraries that work very well with each other. You already sort of seem to know about that as you make use of simplexml_import_dom to convert a DOMNode object into it's SimpleXMLElement object.

You however seem to miss how near you already were. Please see the following example which I copied from your question - I just added a single line at the very end (and change the filename to standard output so it echoes out the documents):

$dom = new domDocument;

$dom->formatOutput = true;
$root = $dom->appendChild($dom->createElement( "user" ));
$sxe = simplexml_import_dom( $dom );
$sxe->addChild("firstname", "John");
$sxe->addChild("surname", "Brady");

$sxe->asXML('php://output');
$dom->save('php://output');

The SimpleXMLElement::saveXML() method will use non-formatted output while the DOMDocument::save() method will use the formatting as you set the parameters for:

<?xml version="1.0"?>
<user><firstname>John</firstname><surname>Brady</surname></user>
<?xml version="1.0"?>
<user>
<firstname>John</firstname>
<surname>Brady</surname>
</user>

And that's it already.

PHP XML how to output nice format

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]);

Format xml with DOM Document AND SimpleXML. Arrgghhh

//Get the wordpress postID
$postID = get_the_ID();

$postData = get_post($postID);

// echo $postID.'<br />'.$postData->post_title.'<br />'.$postData->post_date_gmt.'<br />';

$xmlFile = '/Applications/MAMP/htdocs/giraffetest/test.xml';

// load the document
$xml = simplexml_load_file($xmlFile);

// Check to see if the post id is already in the xml file - has it already been set?
$nodeExists = $xml->xpath("//post[@id=".$postID."]");

//Count the results
$countNodeExists = count($nodeExists);

if($countNodeExists > 0) { // If the ID is already in the file

// echo 'ID already here';

// get the correct node
$result = $xml->xpath("//post[@id=".$postID."]/postviews");

// heres the trick - the first result of xpath, and the node value (stored in [0])
$result[0][0] = $result[0][0]+1;

} else { // If the ID isn;'t there, add a new entry in the xml file for the post

//echo 'ID added';

$postNode = $xml->addChild('post'); // adding a new <post> to the top level node
$postNode->addAttribute('id', $postID); // adding a <postid> inside the new <post>
$postNode->addChild('postviews', 1); // adding a postviews inside the new <post>
}

// save the updated document

//$xml->asXML($xmlFile);
$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xml->asXML());
$dom->save($xmlFile);


Related Topics



Leave a reply



Submit