2010-05-05 31 views
5

Estoy tratando de aprender XSLT pero trabajo mejor con el ejemplo. Quiero realizar un esquema trivial para la transformación de esquema. ¿Cómo realizo esta transformación en una sola pasada (mi solución actual usa dos pasos y pierde el orden original de los clientes)?Cómo seleccionar varios nodos en uno para cada uno XSLT

Desde:

<?xml version="1.0" encoding="UTF-8"?> 
<sampleroot> 

<badcustomer> 
    <name>Donald</name> 
    <address>Hong Kong</address> 
    <age>72</age> 
</badcustomer> 

<goodcustomer> 
    <name>Jim</name> 
    <address>Wales</address> 
    <age>22</age> 
</goodcustomer> 

<goodcustomer> 
    <name>Albert</name> 
    <address>France</address> 
    <age>51</age> 
</goodcustomer> 

</sampleroot> 

Para:

<?xml version="1.0" encoding="UTF-8"?> 
<records> 

<record id="customer"> 
    <name>Donald</name> 
    <address>Hong Kong</address> 
    <age>72</age> 
    <customertype>bad</customertype> 
</record> 

<record id="customer"> 
    <name>Jim</name> 
    <address>Wales</address> 
    <age>22</age> 
    <customertype>good</customertype> 
</record> 

<record id="customer"> 
    <name>Albert</name> 
    <address>France</address> 
    <age>51</age> 
    <customertype>good</customertype> 
</record> 

</records> 

ya lo resolvieron este un mal manera (pierdo el orden de los clientes y creo que tengo que analizar el archivo múltiples veces:

<?xml version='1.0'?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="/sampleroot"> 

    <records> 

     <xsl:for-each select="goodcustomer"> 
      <record id="customer"> 
       <name><xsl:value-of select="name" /></name> 
       <address><xsl:value-of select="address" /></address> 
       <age><xsl:value-of select="age" /></age> 
       <customertype>good</customertype> 
      </record> 
     </xsl:for-each> 

     <xsl:for-each select="badcustomer"> 
      <record id="customer"> 
       <name><xsl:value-of select="name" /></name> 
       <address><xsl:value-of select="address" /></address> 
       <age><xsl:value-of select="age" /></age> 
       <customertype>bad</customertype> 
      </record> 
     </xsl:for-each> 

    </records> 
    </xsl:template> 
</xsl:stylesheet> 

¿Alguien puede ayudarme con la construcción XSLT correcta donde solo tengo que usar un análisis único (solo uno para cada uno)?

Gracias,

Chris

+0

Buena pregunta Chris (+1). Vea mi respuesta para una buena solución. :) –

Respuesta

6

es una buena práctica XSLT para evitar el uso de <xsl:for-each> tanto como sea posible.

Aquí es una solución sencilla, utilizando este principio:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/*"> 
    <records> 
    <xsl:apply-templates/> 
    </records> 
</xsl:template> 

<xsl:template match="badcustomer | goodcustomer"> 
    <record> 
    <xsl:apply-templates/> 
    <customertype> 
    <xsl:value-of select="substring-before(name(), 'customer')"/> 
    </customertype> 
    </record> 
</xsl:template> 
</xsl:stylesheet> 

hacer la nota: se utilizan

  1. Sólo las plantillas y <xsl:apply-templates>.

  2. El uso de la regla de identidad y su anulación cuando sea necesario. Este es uno de los patrones de diseño XSLT más fundamentales.

+0

Gracias, ¿puedo pedir una última información? Si deseo pasar los atributos del esquema xml original, ¿cómo ajustaría el xslt para que esto funcione? Donald Hong Kong Chris

+0

@ Chris: Por favor, pregunte esto como una nueva pregunta, con la adecuada código formateado/xml. Además, está utilizando la palabra "esquema" incorrectamente. En realidad, está consultando el "documento XML de origen" o una instancia del esquema para ese tipo de documento. –

+0

Gracias por la información y por corregir el uso incorrecto de "esquema". Descubrí cómo resolver la pregunta de seguimiento, así que no haré una nueva pregunta ahora. – Chris

Cuestiones relacionadas