2010-10-26 30 views
6

Tengo un xml combinado con un elemento raíz y elementos secundarios de elementos múltiples. Algo como estoDividir XML en PHP

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

Lo que quiero es una manera fácil de analizar el XML y crear una matriz de cadenas XML de los elementos.

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

Estoy buscando una solución elegante, no una solución.

+0

No entiendo cómo esto es relevante? Tengo una tarea particular con esta solución particular. No creo que se pueda cambiar el panorama general. Creo que fui lo suficientemente claro en los requisitos. – danidacar

+0

@user esto simplemente suena como una idea realmente tonta. –

+0

No puedo creer que me hayas votado por no compartir una imagen más amplia, incluso si tienes experiencia en el desarrollo. Lo que pido es claro y no necesito una lección moral. Además, si realmente necesita saber que una tercera parte está enviando un gran archivo xml. Necesito analizar el archivo y enviar a cada cliente la pieza que necesita también como un xml. – danidacar

Respuesta

7

Ok, como ya se mencionó en los comentarios a su pregunta No estoy seguro de que esto sea realmente lo que debería hacer, pero como no soporto SimpleXml y no quiero que la gente piense que es la única manera, así es cómo para hacerlo

con DOM:

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

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

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

* esto también puede hacerse a través de devoluciones de llamada activa cuando se detecta un elemento Item. Tomaría más código, pero es bastante flexible.

Tenga en cuenta que todo lo anterior puede necesitar algunos ajustes dependiendo de su XML real.


Teniendo en cuenta que el XML en su pregunta (que es probable que sólo un ejemplo) es la suciedad simple y bien definido, también se puede utilizar explode():

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

o una expresión regular (leer negación abajo)

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

Negación Ahora, sólo para asegurarse de que no está comenzando a analizar XML con expresiones regulares o Expl ode de forma regular: los dos últimos enfoques solo son posibles si su marcado está realmente tan claramente definido como lo muestra.

+0

No ha mencionado SimpleXmlElement, puede hacer búsquedas xpath. Pero según mi experiencia es como el método Xml() no maneja bien los espacios de nombres. – xmedeko

1

¿Has mirado SimpleXML?

Por ejemplo:

$string = " 
<root> 
    <item>test1</item> 
    <item>test2</item> 
</root> 
"; 

$xml = simplexml_load_string($string); 
+0

Esto no le dará lo que está pidiendo. Dicho esto, no estoy seguro de si lo que está pidiendo es una buena idea –

+0

@Pekka - si, lo sé, pero él quiere una solución elegante para analizar XML y simpleXML es solo eso (imo). Demasiado margen de error de lo contrario – robjmills

+1

Estos son los primeros pasos, estoy de acuerdo ... ¿pero el resto? – danidacar

2

Hay algunos ejemplos de código agradables en los comentarios de SimpleXml manual page. Estoy seguro de que puede hacer que algo funcione desde la muestra objectsIntoArray().