如果 id 重复然后使用 xslt 更改重复的 id
If id repeats then changing the repeated id using xslt
我有一个 xml 输入,其中包含重复的 ID,如下所示
<root>
<p>text 1</p>
<text id="Read-R1">
<p>sample 1</p>
</text>
<p>text 2</p>
<text id="Read-R2">
<p>sample 2</p>
</text>
<p>text 3</p>
<text id="Read-R1">
<p>sample 3</p>
</text>
<p>text 4</p>
<text id="Read-R2">
<p>sample 3</p>
</text>
<p>text 5</p>
<text id="Read-R1">
<p>sample 5</p>
</text>
<text id="Read-R3">
<p>sample 3</p>
</text>
</root>
repeated id 我想将 append -01 更改为 repeated id only first id same as it is:
输出为:
<root>
<p>text 1</p>
<text id="Read-R1">
<p>sample 1</p>
</text>
<p>text 2</p>
<text id="Read-R2">
<p>sample 2</p>
</text>
<p>text 3</p>
<text id="Read-R1-01">
<p>sample 3</p>
</text>
<p>text 4</p>
<text id="Read-R2-01">
<p>sample 3</p>
</text>
<p>text 5</p>
<text id="Read-R1-02">
<p>sample 5</p>
</text>
<text id="Read-R3">
<p>sample 3</p>
</text>
</root>
请建议 xslt 为重复的 ID 附加 -01
提前致谢。
这会带来额外的好处,如果有更多的人使用相同的@id,它仍然会创建唯一的 id。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="text[@id]">
<xsl:variable name="sId" select="@id"/>
<xsl:variable name="iPrecedingIdsWithSameValue" select="count(preceding-sibling::text[@id=$sId])"/>
<xsl:copy>
<xsl:attribute name="id" select="if($iPrecedingIdsWithSameValue gt 0) then concat(@id,'-',format-number($iPrecedingIdsWithSameValue,'00')) else @id"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
您可以使用以下密钥和模板
<xsl:key name="id" match="text" use="@id"/>
<xsl:template match="text[not(. is key('id', @id)[1])]/@id">
<xsl:attribute
name="{name()}"
select="concat(., '-', format-number(index-of(key('id', .)[position() gt 1]/generate-id(), generate-id(..)), '00'))"/>
</xsl:template>
加上身份转换(在 XSLT 3 中由 <xsl:mode on-no-match="shallow-copy"/>
声明或拼写为
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
我有一个 xml 输入,其中包含重复的 ID,如下所示
<root>
<p>text 1</p>
<text id="Read-R1">
<p>sample 1</p>
</text>
<p>text 2</p>
<text id="Read-R2">
<p>sample 2</p>
</text>
<p>text 3</p>
<text id="Read-R1">
<p>sample 3</p>
</text>
<p>text 4</p>
<text id="Read-R2">
<p>sample 3</p>
</text>
<p>text 5</p>
<text id="Read-R1">
<p>sample 5</p>
</text>
<text id="Read-R3">
<p>sample 3</p>
</text>
</root>
repeated id 我想将 append -01 更改为 repeated id only first id same as it is: 输出为:
<root>
<p>text 1</p>
<text id="Read-R1">
<p>sample 1</p>
</text>
<p>text 2</p>
<text id="Read-R2">
<p>sample 2</p>
</text>
<p>text 3</p>
<text id="Read-R1-01">
<p>sample 3</p>
</text>
<p>text 4</p>
<text id="Read-R2-01">
<p>sample 3</p>
</text>
<p>text 5</p>
<text id="Read-R1-02">
<p>sample 5</p>
</text>
<text id="Read-R3">
<p>sample 3</p>
</text>
</root>
请建议 xslt 为重复的 ID 附加 -01 提前致谢。
这会带来额外的好处,如果有更多的人使用相同的@id,它仍然会创建唯一的 id。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="text[@id]">
<xsl:variable name="sId" select="@id"/>
<xsl:variable name="iPrecedingIdsWithSameValue" select="count(preceding-sibling::text[@id=$sId])"/>
<xsl:copy>
<xsl:attribute name="id" select="if($iPrecedingIdsWithSameValue gt 0) then concat(@id,'-',format-number($iPrecedingIdsWithSameValue,'00')) else @id"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
您可以使用以下密钥和模板
<xsl:key name="id" match="text" use="@id"/>
<xsl:template match="text[not(. is key('id', @id)[1])]/@id">
<xsl:attribute
name="{name()}"
select="concat(., '-', format-number(index-of(key('id', .)[position() gt 1]/generate-id(), generate-id(..)), '00'))"/>
</xsl:template>
加上身份转换(在 XSLT 3 中由 <xsl:mode on-no-match="shallow-copy"/>
声明或拼写为
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>