XSLT多输出:复制选定的节点,其余的也是

时间:2015-06-09 15:00:19

标签: xml xslt xslt-2.0

我有以下输入xml:

<?xml version="1.0" encoding="UTF-8"?>
<car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <extras>
      <extra>
         <model>Z1</model>
      </extra>
      <extra>
         <model>Z2</model>
      </extra>
      <extra>
         <model>X</model>
      </extra>
   </extras>
   <color>red</color>
   <tire>goodyear</tire>
</car>

我正在尝试为每个<extra>..</extra>元素生成一个输出xml,结果xmls应该包含输入中的所有元素,但只包含一个特定的<extra>元素。 即,结果输出应为:

extra1.xml:

<?xml version="1.0" encoding="UTF-8"?>
<car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <extras>
      <extra>
         <model>Z1</model>
      </extra>
   </extras>
   <color>red</color>
   <tire>goodyear</tire>
</car>

extra2.xml:

<?xml version="1.0" encoding="UTF-8"?>
<car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <extras>
      <extra>
         <model>Z2</model>
      </extra>
   </extras>
   <color>red</color>
   <tire>goodyear</tire>
</car>

extra3.xml:

<?xml version="1.0" encoding="UTF-8"?>
<car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <extras>
      <extra>
         <model>X</model>
      </extra>
   </extras>
   <color>red</color>
   <tire>goodyear</tire>
</car>

我正在使用XSLT 2.0 Saxon-HE 9.6.0-5。

我的xslt如下所示:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" encoding="UTF-8" indent="yes" />
    <xsl:strip-space elements="*" />

    <xsl:template name="full">
        <xsl:param name="enode" />
        <xsl:for-each select="/">
            <xsl:if test="*[not($enode = current())]">
                <xsl:copy-of select="current()" />
            </xsl:if>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="extras">
        <xsl:for-each select="//extra">
            <xsl:result-document href="extra{position()}.xml">
                <xsl:call-template name="full">
                    <xsl:with-param name="enode" select="current()" />
                </xsl:call-template>
                <extras>
                    <xsl:copy-of select="current()" />
                </extras>
            </xsl:result-document>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

我能够生成仅包含一个<extra>元素的输出xmls,但是如何从输入中复制其余元素(即: 除<extras>的孩子以外的所有元素?) 我试图创建一个模板“full”,它循环遍历所有节点,只复制那些与我作为参数(enode)传递的节点不同的模板,但没有成功。
有没有(其他)方法来获得所需的结果?
如果生成的xml中元素的顺序不同,我提供的不是问题,我可以在第二遍中重新排列它们。

1 个答案:

答案 0 :(得分:1)

不能简单地说:

XSLT 2.0

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />

<xsl:template match="/car">
    <xsl:for-each select="extras/extra">
        <xsl:result-document href="extra{position()}.xml">
            <car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                <extras>
                     <xsl:copy-of select="*"/>
                </extras>
                <xsl:copy-of select="../../(* except extras)"/>
            </car>
        </xsl:result-document>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>