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

Posted

技术标签:

【中文标题】通过 XSLT 在其他两个元素之间添加元素?【英文标题】:Add element between two other elements via XSLT? 【发布时间】:2018-03-18 18:54:36 【问题描述】:

我有以下输入 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>

但我没有得到我想要的输出。如何使用标识模板将ccc 元素放在bbbddd 元素之间?

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

【问题讨论】:

这里不需要 XSLT 3.0 —— XSLT 1.0 就足够了。 【参考方案1】:

使用与插入点之前或之后的元素匹配的第二个模板进行身份转换,然后在复制匹配的元素之后或之前插入新元素。也就是说:

鉴于此输入 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>

【讨论】:

【参考方案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>

使用&lt;xsl:mode on-no-match="shallow-copy"/&gt; 表示身份转换并使用&lt;xsl:next-match/&gt;ddd 元素的复制委托给它。

【讨论】:

很高兴看到 XSLT 3.0 解决方案进行比较。

以上是关于通过 XSLT 在其他两个元素之间添加元素?的主要内容,如果未能解决你的问题,请参考以下文章

XSLT - 动态添加元素

XSLT Grouping's:将父级添加到子元素中的元素集

XSLT:将命名空间添加到根元素

xslt 1.0 添加新元素

使用 XSLT 选择最后一个子元素

XSLT 如何组合模板并将现有字段添加到某些元素