使用xpath在相同节点中查找具有特定文本的节点的位置

使用xpath在相同节点中查找具有特定文本的节点的位置,xpath,xslt-2.0,Xpath,Xslt 2.0,在单个文档中有一组商标节点。每个节点中都包含文本节点-商标名。tm的之间可能存在相同的节点,这意味着它们具有相同的商标名。我需要写的模板,将添加商标字符™ (™;)仅适用于每个商标的第一次出现 例如: <doc> <a><tm>A</tm></a> <tm>A</tm> <tm>B</tm> <b><tm>B</tm></

在单个文档中有一组商标节点
。每个节点
中都包含文本节点-商标名。
tm的
之间可能存在相同的节点,这意味着它们具有相同的商标名。我需要写的模板,将添加商标字符™ (
™;
)仅适用于每个商标的第一次出现

例如:

<doc>
  <a><tm>A</tm></a>
  <tm>A</tm>
  <tm>B</tm>
  <b><tm>B</tm></b>
  <a><b><c><tm>A</tm></c></b></a>
</doc>

A.
A.
B
B
A.
只应处理第一次出现的
A
B

预期结果是:

<doc>
  <a><tm>A&#8482;</tm></a>
  <tm>A</tm>
  <tm>B&#8482;</tm>
  <b><tm>B</tm></b>
  <a><b><c><tm>A</tm></c></b></a>
</doc>

A™;
A.
B™;
B
A.
这里的困难在于存在相同的节点。此外,我不能为每个商标编写单独的模板,一个模板应该匹配所有商标

以下是解决方案草案:

<xsl:template match="tm">
  <xsl:variable name="text" select="text()"/>
  <xsl:variable name="same_tms" select="//tm[text()=$text]"/>
  <xsl:if test=" --- current tm is the first among $same_tms --- ">
    <xsl:value-of select="concat(text(), '&#8482;')"/>
  </xsl:if>
</xsl:template>


我不知道如何编写一个通用测试条件来检查当前的
是否是
$same\u tms
中的第一个。有可能吗?

使用一个键,就像在Muenchian分组()中一样,只有在XSLT 2.0中可以使用
Is
而不是XSLT 1.0中需要的
generate-id()
测试:

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

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

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

    <xsl:template match="tm[. is key('tm', .)[1]]">
        <xsl:copy>
            <xsl:value-of select="concat(., '&#8482;')"/>
        </xsl:copy>
    </xsl:template>
</xsl:transform>


在线作为。

显然,
操作员也会作为
解决您的方法。是$same\u tms[1]