¿Cómo se puede convertir un xml a otro xml según el valor de la etiqueta xpath en PHP?

¿Cómo puedo convertir xml a otro formato xml usando xpath? El archivo xml es dinámico, podría tener cualquier nivel, diferentes etiquetas. El siguiente xml es un ejemplo:

<?xml version="1.0"?> 
<student_info>     
<total_stud>500</total_stud>     
  <student>         
    <id>1</id>         
    <name>abc</name>         
    <address>             
       <city>Pune</city>             
       <zip>411006</zip>         
    </address>     
  </student>     
  <student>         
    <id>1</id>         
    <name>bbc</name>         
    <address>             
      <city>Toronto</city>             
      <zip>82233</zip>         
    </address>     
  </student> 
  <student>         
    <id>2</id>         
    <name>wec</name>         
    <address>             
      <city>North York</city>             
      <zip>59522</zip>         
    </address>     
  </student> 
</student_info> 

Para: todo el estudiante "id=1"

<?xml version="1.0"?>
<student_info>
  <student>
    <name>abc</name>
    <city>Pune</city>             
    <zip>411006</zip>      
  </student> 
  <student>
    <name>bbc</name>
    <city>Toronto</city>             
    <zip>82233</zip>      
  </student>
</student_info>

preguntado el 04 de julio de 12 a las 01:07

¿Alguien puede ayudar con eso? ¡Gracias! -

Sospecho que te refieres a cómo transformar un documento XML en otro usando XSLT. XPath es una tecnología de componentes de XSLT que tiene que ver con la "navegación" de los nodos y atributos en XML. -

2 Respuestas

Probablemente desee utilizar una transformación XSL, que facilita XPath.

Puedes usarlo desde PHP así: http://www.php.net/manual/en/book.xsl.php

El XSL para su ejemplo podría verse así:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes"/>

  <xsl:param name="id" />

  <xsl:template match="/student_info">
    <xsl:copy>
      <xsl:apply-templates select=".//student[id=$id]"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="student">
    <xsl:copy>
      <xsl:copy-of select="name" />
      <xsl:copy-of select="address/city" />
      <xsl:copy-of select="address/zip" />
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Puedes pasar el id parámetro (usado dentro de la hoja de estilo usando <xsl:param> y $id) al transformador usando setParameter.

EDITAR: Aquí hay una porción de xsltCake para jugar: http://www.xsltcake.com/slices/dnuFXh Desafortunadamente, no admite parámetros.

Respondido 08 Jul 12, 00:07

Prueba esto:

// guardarlo en un archivo: ts1.xml

<?xml version="1.0" encoding="utf-8"?>
<student_info>     
    <total_stud>500</total_stud>     
  <student>         
    <id>1</id>         
    <name>abc</name>         
    <address>             
       <city>Pune</city>             
       <zip>411006</zip>         
    </address>     
  </student>     
  <student>         
    <id>1</id>         
    <name>bbc</name>         
    <address>             
      <city>Toronto</city>             
      <zip>82233</zip>         
    </address>     
  </student> 
  <student>         
    <id>2</id>         
    <name>wec</name>         
    <address>             
      <city>North York</city>             
      <zip>59522</zip>         
    </address>     
  </student> 
</student_info>

Código PHP aquí:

<?php
$xml = simplexml_load_file( 'ts1.xml' );

// search all nodes with id=1
$xpath = ( $xml->xpath( '//student/id[.=1]/..' ) );

// create a new XML
$newXML = simplexml_load_string( "<?xml version=\"1.0\" encoding=\"utf-8\"?><student_info></student_info>" );

// add matching xml nodes to it.
foreach( $xpath as $st ) {
    $student = $newXML->addChild( 'student' );
    $student->addChild( 'name', (string)$st->name );
    $student->addChild( 'city', (string)$st->address->city );
    $student->addChild( 'zip', (string)$st->address->zip );
}

$xmldoc = new DomDocument( '1.0' );
$xmldoc->preserveWhiteSpace = false;
$xmldoc->formatOutput = true;

$xmldoc->loadXML( $newXML->asXML(), LIBXML_NOBLANKS );
//save as 1.xml
$xmldoc->save( '1.xml' );
?>

Resultado guardado en 1.xml

<?xml version="1.0" encoding="utf-8"?>
<student_info>
  <student>
    <name>abc</name>
    <city>Pune</city>
    <zip>411006</zip>
  </student>
  <student>
    <name>bbc</name>
    <city>Toronto</city>
    <zip>82233</zip>
  </student>
</student_info>

Esto creará un nuevo xml para todos los nodos con id=1. Puedes modificarlo para adaptarlo a tus necesidades. Espero que esto ayude.

Respondido 04 Jul 12, 08:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.