使用 xpath 在相同节点中查找具有特定文本的节点的位置
Find position of a node with specific text among identical nodes using xpath
单个文档中有一组商标节点<tm>
。每个节点 <tm>
包含里面的文本节点 - 商标名称。 tm's
中可能有相同的节点,这意味着它们具有相同的商标名称。我需要编写将商标字符™ (™
) 添加到每个商标第一次出现的模板。
示例:
<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>
只应处理第一次出现的 <tm>A</tm>
和 <tm>B</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>
这里的困难在于有相同的节点。另外,我不能为每个商标单独写一个模板,一个模板应该匹配所有。
这是解决方案的草稿:
<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(), '™')"/>
</xsl:if>
</xsl:template>
我不知道如何编写通用测试条件来检查当前 <tm>
是否是 $same_tms
中的第一个。可能吗?
使用一个键,就像在 Muenchian 分组 (http://www.jenitennison.com/xslt/grouping/muenchian.xml) 中一样,只有在 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(., '™')"/>
</xsl:copy>
</xsl:template>
</xsl:transform>
单个文档中有一组商标节点<tm>
。每个节点 <tm>
包含里面的文本节点 - 商标名称。 tm's
中可能有相同的节点,这意味着它们具有相同的商标名称。我需要编写将商标字符™ (™
) 添加到每个商标第一次出现的模板。
示例:
<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>
只应处理第一次出现的 <tm>A</tm>
和 <tm>B</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>
这里的困难在于有相同的节点。另外,我不能为每个商标单独写一个模板,一个模板应该匹配所有。
这是解决方案的草稿:
<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(), '™')"/>
</xsl:if>
</xsl:template>
我不知道如何编写通用测试条件来检查当前 <tm>
是否是 $same_tms
中的第一个。可能吗?
使用一个键,就像在 Muenchian 分组 (http://www.jenitennison.com/xslt/grouping/muenchian.xml) 中一样,只有在 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(., '™')"/>
</xsl:copy>
</xsl:template>
</xsl:transform>