使用 xslt-3 使 xml 元素唯一
make xml element unique using xslt-3
给定以下示例 xml,我如何使 RECORD ID 元素和 TITLEID 具有唯一值,从值 1 开始,然后继续?
<CATALOG>
<CD>
<RECORD ID="109">
<TITLEID>54</TITLEID>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR> </CD>
</RECORD>
<CD>
<RECORD ID="187">
<TITLEID>88</TITLEID>
<ARTIST>Bonnie Tyler</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>CBS Records</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1988</YEAR> </CD>
</RECORD>
</CATALOG>
预期结果:
<CATALOG>
<CD>
<RECORD ID="1">
<TITLEID>1</TITLEID>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR> </CD>
</RECORD>
<CD>
<RECORD ID="2">
<TITLEID>2</TITLEID>
<ARTIST>Bonnie Tyler</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>CBS Records</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1988</YEAR> </CD>
</RECORD>
</CATALOG>
我尝试使用 xs:unique 属性,但我未能使其正常工作
使用累加器的 XSLT 3 解决方案(https://www.w3.org/TR/xslt-30/#element-accumulator) is at https://xsltfiddle.liberty-development.net/6qVRKwn/0 并
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="3.0">
<xsl:mode on-no-match="shallow-copy" use-accumulators="cd-count"/>
<xsl:accumulator name="cd-count" as="xs:integer" initial-value="0">
<xsl:accumulator-rule match="CD" select="$value + 1"/>
</xsl:accumulator>
<xsl:template match="RECORD/@ID">
<xsl:attribute name="{name()}" select="..!accumulator-before('cd-count')"/>
</xsl:template>
<xsl:template match="RECORD/TITLEID">
<xsl:copy>
<xsl:value-of select="accumulator-before('cd-count')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
经典的解决方案是使用 xsl:number
(https://www.w3.org/TR/xslt-30/#element-number), as in https://xsltfiddle.liberty-development.net/6qVRKwn/1:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="RECORD/@ID">
<xsl:attribute name="{name()}">
<xsl:number count="CD"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="RECORD/TITLEID">
<xsl:copy>
<xsl:number count="CD"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
给定以下示例 xml,我如何使 RECORD ID 元素和 TITLEID 具有唯一值,从值 1 开始,然后继续?
<CATALOG>
<CD>
<RECORD ID="109">
<TITLEID>54</TITLEID>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR> </CD>
</RECORD>
<CD>
<RECORD ID="187">
<TITLEID>88</TITLEID>
<ARTIST>Bonnie Tyler</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>CBS Records</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1988</YEAR> </CD>
</RECORD>
</CATALOG>
预期结果:
<CATALOG>
<CD>
<RECORD ID="1">
<TITLEID>1</TITLEID>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR> </CD>
</RECORD>
<CD>
<RECORD ID="2">
<TITLEID>2</TITLEID>
<ARTIST>Bonnie Tyler</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>CBS Records</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1988</YEAR> </CD>
</RECORD>
</CATALOG>
我尝试使用 xs:unique 属性,但我未能使其正常工作
使用累加器的 XSLT 3 解决方案(https://www.w3.org/TR/xslt-30/#element-accumulator) is at https://xsltfiddle.liberty-development.net/6qVRKwn/0 并
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="3.0">
<xsl:mode on-no-match="shallow-copy" use-accumulators="cd-count"/>
<xsl:accumulator name="cd-count" as="xs:integer" initial-value="0">
<xsl:accumulator-rule match="CD" select="$value + 1"/>
</xsl:accumulator>
<xsl:template match="RECORD/@ID">
<xsl:attribute name="{name()}" select="..!accumulator-before('cd-count')"/>
</xsl:template>
<xsl:template match="RECORD/TITLEID">
<xsl:copy>
<xsl:value-of select="accumulator-before('cd-count')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
经典的解决方案是使用 xsl:number
(https://www.w3.org/TR/xslt-30/#element-number), as in https://xsltfiddle.liberty-development.net/6qVRKwn/1:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="RECORD/@ID">
<xsl:attribute name="{name()}">
<xsl:number count="CD"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="RECORD/TITLEID">
<xsl:copy>
<xsl:number count="CD"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>