使用xslt 2.0将字符串附加到xml文档中的属性

时间:2015-03-13 14:46:07

标签: xml xslt

我有一个包含id的元素的xml属性,其中一些id可能会出现多次。在这种情况下,我想将_copy附加到除了具有该id的第一个元素之外的所有元素。

所以我的xml文件如下所示:

<elems>
<elem id="123"/>
<elem id="2832"/>
<elem id="2272"/>
<elem id="123"/>
<elem id="123"/>
</elems>

期望的输出:

<elems>
<elem id="123"/>
<elem id="2832"/>
<elem id="2272"/>
<elem id="123_copy"/>
<elem id="123_copy"/>
</elems>

最好的方法是什么?我正在考虑将文档读入变量,然后检查id是否出现多次......

感谢您的帮助和提示!

3 个答案:

答案 0 :(得分:3)

这个XSLT会解决你的问题:

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

    <xsl:key name="element" match="elem" use="@id"/>

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

    <xsl:template match="elem[count(key('element', @id)[1] | .) = 2]">
        <elem id="{concat(@id, '_copy')}"/>
    </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:2)

我会键入属性本身并使用XPath 2.0 is运算符编写条件:

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

<xsl:param name="marker" select="'_copy'"/>

<xsl:key name="id" match="@id" use="."/>

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

<xsl:template match="@id[not(. is key('id', .)[1])]">
  <xsl:attribute name="{name()}" select="concat(., $marker)"/>
</xsl:template>

</xsl:stylesheet>

答案 2 :(得分:2)

  

我刚试过for-each-group。我如何附加&#34; _copy&#34;?

怎么样:

XSLT 2.0

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

<xsl:template match="/elems">
    <xsl:copy>
        <xsl:for-each-group select="elem" group-by="@id">
            <xsl:for-each select="current-group()">
                <elem id="{@id}{if(position() gt 1) then '_copy' else ''}"/>
            </xsl:for-each>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>