2012-10-20 7 views
6

Ho un pezzo di XML che voglio trasformare con XSLT (usando xsltproc - quindi solo XSLT 1.0). L'XML originale utilizza alcuni tag come separatori come questo:Usa XSLT per convertire i separatori in wrapper

<container> 
    <element /> 
    <element /> 
    <separator /> 
    <element /> 
    <element /> 
    <element /> 
    <separator /> 
    <element /> 
</container> 

Ho bisogno di trasformare questo in un formato che avvolge invece questi elementi. Quindi ho bisogno che assomigli a questo:

<container> 
    <wrapper> 
    <element /> 
    <element /> 
    </wrapper> 
    <wrapper> 
    <element /> 
    <element /> 
    <element /> 
    </wrapper> 
    <wrapper> 
    <element /> 
    </wrapper> 
</container> 

Non riesco proprio a progettare un modello che lo ottenga. Qualcuno là fuori ha qualche idea?

risposta

6

Questa trasformazione:

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

<xsl:key name="kFollowing" match="element" 
      use="generate-id(preceding-sibling::separator[1])"/> 

<xsl:template match="/*"> 
    <container> 
     <xsl:apply-templates select= 
     "element 
      [generate-id() 
      = 
      generate-id(key('kFollowing', 
          generate-id(preceding-sibling::separator[1]) 
          )[1] 
         ) 
      ]"/> 
    </container> 
</xsl:template> 

<xsl:template match="element"> 
    <wrapper> 
    <xsl:copy-of select= 
    "key('kFollowing', 
     generate-id(preceding-sibling::separator[1]) 
     )"/> 
    </wrapper> 
</xsl:template> 
</xsl:stylesheet> 

quando applicato sul documento XML fornito:

<container> 
    <element /> 
    <element /> 
    <separator /> 
    <element /> 
    <element /> 
    <element /> 
    <separator /> 
    <element /> 
</container> 

produce il desiderato, risultato corretto:

<container> 
    <wrapper> 
     <element/> 
     <element/> 
    </wrapper> 
    <wrapper> 
     <element/> 
     <element/> 
     <element/> 
    </wrapper> 
    <wrapper> 
     <element/> 
    </wrapper> 
</container> 
+0

Grazie! Non avevo pensato di usare la chiave e generare id in quel modo. –

+0

@JeffKing, prego. Questa è una variante del raggruppamento "posizionale". Questo è molto più facile da realizzare in XSLT 2.0, –