2010-09-28 46 views
0

我想包裝<foo/>的子節點,它們不是<bar/><baz/><corge/>用XSL包裝某些節點

注:<bar/><baz/>將永遠是轉換如此<foo/>

第一子節點:

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

這樣:

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

有什麼好辦法做到這一點使用XSL?

回答

1

這個樣式表:

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

輸出:

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

注意:拉風格和模式的應用模板。如果沒有用於換行的元素,則不會輸出corge元素。

其他樣式表(代碼緊湊,可重複使用的少):

<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

這是我會怎麼做了吧...

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> 

輸出

<?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推送式的例子。 – 2010-09-28 19:45:25