2010-05-05 14 views
5

Sto cercando di imparare XSLT, ma lavoro meglio con l'esempio. Voglio eseguire uno schema banale per la trasformazione dello schema. Come posso eseguire questa trasformazione in un solo passaggio (la mia soluzione corrente utilizza due passaggi e perde l'ordine originale dei clienti)?Come selezionare più nodi in singolo XSLT

Da:

<?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> 

A:

<?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> 

ho già risolto un brutto modo (perdo l'ordine dei clienti e penso che devo analizzare il file più volte:

<?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> 

Per favore qualcuno può aiutarmi con il costrutto XSLT corretto in cui devo solo usare un singolo parse (solo uno per-ciascuno)?

Grazie,

Chris

+0

Buona domanda Chris (+1). Vedi la mia risposta per una buona soluzione. :) –

risposta

6

Si tratta di una buona pratica XSLT per evitare l'uso di <xsl:for-each> il più possibile.

Ecco una soluzione semplice, utilizzando questo 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> 

Do atto:

  1. Solo modelli e <xsl:apply-templates> vengono utilizzati.

  2. L'uso della regola di identità e la sua sovrascrittura ove necessario. Questo è uno dei pattern di progettazione XSLT più fondamentali.

+0

Grazie, posso chiedere un'ultima informazione. Se desidero passare gli attributi dallo schema xml originale, come faccio a regolare xslt affinché funzioni? Donald Hong Kong Chris

+0

@ Chris: Si prega di chiedere a questa come una nuova domanda, in modo adeguato codice formattato/xml. Inoltre, stai usando la parola "schema" in modo errato. Si sta effettivamente riferendo al "documento XML di origine" oa un'istanza dello schema per quel tipo di documento. –

+0

Grazie per le informazioni e per correggere il mio uso scorretto di "schema". Ho capito come risolvere la domanda di follow-up quindi non farò una nuova domanda ora. – Chris

Problemi correlati