通过XSLT在两个其他元素之间添加元素?

时间:2017-10-06 22:18:43

标签: xml xslt xslt-3.0

我有以下输入XML:

<root>
    <aaa>some string aaa</aaa>
    <bbb>some string bbb</bbb>
    <ddd>some string ddd</ddd> 
</root>

使用XSLT我想要以下输出:

<root>
    <aaa>some string aaa</aaa>
    <bbb>some string bbb</bbb>
    <ccc>some string ccc</ccc>
    <ddd>some string ddd</ddd>
</root>

我的XSLT是:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="root">
        <root>
            <ccc>some string ccc</ccc>
            <xsl:apply-templates select="@*|node()"/> 
        </root>
    </xsl:template>
</xsl:stylesheet>

但我没有得到我想要的输出。如何使用身份模板在cccbbb元素之间放置ddd元素?

如果有帮助,我可以使用XSLT 3.0。

2 个答案:

答案 0 :(得分:2)

将标识转换与第二个模板一起使用,该模板与插入点之前或之后的元素匹配,然后在复制匹配元素之后或之前插入新元素。即:

鉴于此输入XML,

<root>
   <aaa>some string aaa</aaa>
   <bbb>some string bbb</bbb>
   <ddd>some string ddd</ddd> 
</root>

此XSLT,

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="ddd">
    <ccc>some string ccc</ccc>
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

将生成此输出XML:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <aaa>some string aaa</aaa>
   <bbb>some string bbb</bbb>
   <ccc>some string ccc</ccc>
   <ddd>some string ddd</ddd> 
</root>

答案 1 :(得分:2)

Kenneth的答案很好,但由于问题被标记为XSLT 3.0,因此可以写得更紧凑,所以我将此答案添加为替代

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0">

    <xsl:output indent="yes"/>

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:template match="ddd">
        <ccc>some string ccc</ccc>
        <xsl:next-match/>
    </xsl:template>

</xsl:stylesheet>

使用<xsl:mode on-no-match="shallow-copy"/>来表达身份转换,并使用<xsl:next-match/>委托将ddd元素复制到其中。