用XSL包装某些节点

时间:2010-09-28 14:47:12

标签: xml xslt

我想将<foo/>的{​​{1}}或<bar/>的子节点包裹在<baz/>中。

注意:<corge/><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>

使用XSL执行此操作的好方法是什么?

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分: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>