Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split XML in PHP

Tags:

php

xml

I have a merged xml with a root element and multiple item child elements. Something like this

 <root>
  <item>test1</item>
  <item>test2</item>
 </root>

What I want is an easy way to parse the xml and create an array of xml strings from the items.

$arrXml[0] = '<item>test1</item>';
$arrXml[1] = '<item>test2</item>';

I'm looking for an elegant solution not any solution.

like image 909
johnlemon Avatar asked Oct 26 '10 08:10

johnlemon


People also ask

How to split XML file in PHP?

We do this by writing a XMLparser that will extract each "chunk" of N (here N=5) items and feed it to a chunk processor, which upon receiving ... will wrap it between tags, add a XML header, and thus produce a file with the same syntax of the original big file, but with only five items.

How to use split in XML?

XML DOM splitText() MethodThe splitText() method splits the text node into two nodes at the specified offset. This function returns the node containing the text after the offset. The text before the offset remains in the original text node.

What is XML parser PHP?

An XML Parser is a program that translates XML an XML document into a DOM tree-structure like document. CDATA is used to ignore special characters when parsing XML documents. PHP uses the simplexml_load_file to read XML documents and return the results as a numeric array. PHP DOMDocument class to create XML files.


2 Answers

Ok, like already mentioned in the comments to your question I am not convinced this is really what you should be doing, but since I cant stand SimpleXml and dont want people to think it's the only way, here is how to do it

with DOM:

$arrXml = array();
$dom    = new DOMDocument;
$dom->loadXML( $xml );
foreach( $dom->getElementsByTagName( 'item' ) as $item ) {
    $arrXml[] = $dom->saveXML( $item );
}
print_r( $arrXml );

with XMLReader:

$arrXml = array();
$reader = new XmlReader;
$reader->xml( $xml );
while( $reader->read() ) {
    if( $reader->localName === 'item' && $reader->nodeType === 1 ) {
        $arrXml[] = $reader->readOuterXml();
    }
}
print_r( $arrXml );

and XMLParser*:

xml_parse_into_struct(xml_parser_create(), $xml, $nodes);
$xmlArr = array();
foreach($nodes as $node) {
    if($node['tag'] === 'ITEM') {
        $arrXml[] = "<item>{$node['value']}</item>";
    }
}
print_r($arrXml);

* this can also be done via callbacks triggered when an ITEM element is encountered. Would take more code, but is pretty flexible.

Note that all of the above might need some tweaking depending on your real XML.


Given that the XML in your question (which is likely only an example) is dirt simple and well defined, you can also use explode():

$arrXml = array_map( 'trim',
    array_filter(
        explode( PHP_EOL, $xml ),
        function( $line ) { return substr( $line, 0, 6 ) === '<item>'; }
));
print_r( $arrXml );

or a Regex (read disclaimer below)

preg_match_all('#<item>.*</item>#', $xml, $arrXml);
print_r($arrXml[0]);

Disclaimer Now, just to make sure you are not starting to parse XML with Regex or Explode on a regular basis: The last two approaches are only feasible if your markup is really that clearly defined as you show it.

like image 93
Gordon Avatar answered Sep 21 '22 00:09

Gordon


There are some nice code examples in the comments of SimpleXml manual page. I am sure you can make something work from objectsIntoArray() sample.

like image 43
renick Avatar answered Sep 21 '22 00:09

renick