2010-09-28 3 views
0

Je veux envelopper les nœuds enfants de <foo/> qui ne sont pas <bar/> ou <baz/> avec <corge/>.Envelopper certains nœuds avec XSL

Note: <bar/> et <baz/> seront toujours les premiers nœuds enfants de <foo/>

Converting ceci:

<root> 
    <foo> 
     <bar>bar</bar> 
     <baz>baz</baz> 
     <qux>qux</qux> 
     <grault>grault</grault> 
    </foo> 
    <foo> 
     <bar>bar</bar> 
     <baz>baz</baz> 
     <qux>qux</qux> 
     <quux>quux</quux> 
    </foo> 
</root> 

à ceci:

<root> 
    <foo> 
     <bar>bar</bar> 
     <baz>baz</baz> 
     <corge> 
      <qux>qux</qux> 
      <grault>grault</grault> 
     </corge> 
    </foo> 
    <foo> 
     <bar>bar</bar> 
     <baz>baz</baz> 
     <corge> 
      <qux>qux</qux> 
      <quux>quux</quux> 
     </corge> 
    </foo> 
</root> 

Qu'est-ce qu'une bonne façon de faire en utilisant XSL?

Répondre

1

Cette feuille de style:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="node()|@*" name="identity"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="foo/*"/> 
    <xsl:template match="foo/bar|foo/baz"> 
     <xsl:call-template name="identity"/> 
    </xsl:template> 
    <xsl:template match="foo/*[not(self::bar or self::baz)][1]"> 
     <corge> 
      <xsl:apply-templates select="../*[not(self::bar or self::baz)]" 
           mode="corge"/> 
     </corge> 
    </xsl:template> 
    <xsl:template match="foo/*" mode="corge"> 
     <xsl:call-template name="identity"/> 
    </xsl:template> 
</xsl:stylesheet> 

Sortie:

<root> 
    <foo> 
     <bar>bar</bar> 
     <baz>baz</baz> 
     <corge> 
      <qux>qux</qux> 
      <grault>grault</grault> 
     </corge> 
    </foo> 
    <foo> 
     <bar>bar</bar> 
     <baz>baz</baz> 
     <corge> 
      <qux>qux</qux> 
      <quux>quux</quux> 
     </corge> 
    </foo> 
</root> 

Remarque: Tirez le style et les modes d'application des modèles. S'il n'y a aucun élément pour l'emballage, l'élément corge ne sera pas produit.

Autres stylesheet (code compact, moins réutilisable):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="root"> 
     <root> 
      <xsl:apply-templates/> 
     </root> 
    </xsl:template> 
    <xsl:template match="foo"> 
     <foo> 
      <xsl:copy-of select="bar|baz"/> 
      <corge> 
       <xsl:copy-of select="*[not(self::bar or self::baz)]"/> 
      </corge> 
     </foo> 
    </xsl:template> 
</xsl:stylesheet> 
0

Voici comment je l'ai fait ...

XML

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <foo> 
    <bar>bar</bar> 
    <baz>baz</baz> 
    <qux>qux</qux> 
    <grault>grault</grault> 
    </foo> 
    <foo> 
    <bar>bar</bar> 
    <baz>baz</baz> 
    <qux>qux</qux> 
    <quux>quux</quux> 
    </foo> 
</root> 

XSL

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
    </xsl:template> 
    <xsl:template match="foo"> 
    <foo> 
     <xsl:apply-templates select="bar|baz"/> 
     <corge> 
     <xsl:apply-templates select="*[name() != 'bar' and name() != 'baz']"/> 
     </corge> 
    </foo> 
    </xsl:template> 
</xsl:stylesheet> 

SORTIE

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <foo> 
     <bar>bar</bar> 
     <baz>baz</baz> 
     <corge> 
     <qux>qux</qux> 
     <grault>grault</grault> 
     </corge> 
    </foo> 
    <foo> 
     <bar>bar</bar> 
     <baz>baz</baz> 
     <corge> 
     <qux>qux</qux> 
     <quux>quux</quux> 
     </corge> 
    </foo> 
</root> 
+0

+1 par exemple de style push. –

Questions connexes