XSLT - 动态地向节点添加属性
XSLT - add attribute to node dynamically
我有 xml 如下,
<doc>
<p type="Foot">
<link ref="http://www.facebook.com">
<c type="Hyperlink">www.facebook.com</c>
</link>
</p>
<p type="End">
<link ref="http://www.google.com">
<c type="Hyperlink">www.google.com.com</c>
</link>
</p>
</doc>
我需要做的是将动态 id 属性添加到具有属性 "Foot"
和 "End"
的 <p>
节点。所以我写了以下 xsl,
<xsl:template match="p[@type='Foot' or @type='End']" priority="1">
<xsl:copy>
<xsl:attribute name="id">
<xsl:value-of select="'foot-'"/>
<xsl:number count="p[@type='Foot' or @type='End']" level="any"/>
</xsl:attribute>
<xsl:next-match/>
</xsl:copy>
</xsl:template>
它给了我以下结果
<doc>
<p id="foot-1"><p type="Foot">
<link ref="http://www.facebook.com">
<c type="Hyperlink">www.facebook.com</c>
</link>
</p></p>
<p id="foot-2"><p type="End">
<link ref="http://www.google.com">
<c type="Hyperlink">www.google.com.com</c>
</link>
</p></p>
</doc>
如上结果 xml,它添加了重复的
节点并添加了新属性。但我需要的是这个,
<doc>
<p id="foot-1 type="Foot">
<link ref="http://www.facebook.com">
<c type="Hyperlink">www.facebook.com</c>
</link>
</p></p>
<p id="foot-2 type="End">
<link ref="http://www.google.com">
<c type="Hyperlink">www.google.com.com</c>
</link>
</p></p>
</doc>
如何通过更改 mu xsl 获得此输出?
我认为您的问题很可能是我们无法从您的问题中看出的 - 您正在调用 xsl:next-match
,在一个模板中,该模板已经从 xsl:copy
指令。如果下一场比赛,无论碰巧是什么,xsl:copy
,你都会在第一个标签中得到第二个 p
标签,就像你看到的那样。
听起来您需要做的是拥有另一个具有更高优先级且仅匹配 p
的模板,执行 <xsl:copy>
,在其中调用 <xsl:next-match>
然后处理子节点, 并从匹配特定案例的低优先级模板中删除 <xsl:copy>
。
<xsl:template match="p" priority="2">
<xsl:copy>
<xsl:next-match/>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="p[@type='Foot']" priority="1">
<xsl:attribute name="id">
<xsl:value-of select="'foot-'"/>
<xsl:number count="p[@type='Foot' or @type='End']" level="any"/>
</xsl:attribute>
<xsl:next-match/>
</xsl:template>
etc..
顺便说一下,您不需要 <xsl:value-of select="'foot-'"/>
- 如果它只是一个常量,那么 <xsl:text>foot-</xsl:text>
就可以了。
我有 xml 如下,
<doc>
<p type="Foot">
<link ref="http://www.facebook.com">
<c type="Hyperlink">www.facebook.com</c>
</link>
</p>
<p type="End">
<link ref="http://www.google.com">
<c type="Hyperlink">www.google.com.com</c>
</link>
</p>
</doc>
我需要做的是将动态 id 属性添加到具有属性 "Foot"
和 "End"
的 <p>
节点。所以我写了以下 xsl,
<xsl:template match="p[@type='Foot' or @type='End']" priority="1">
<xsl:copy>
<xsl:attribute name="id">
<xsl:value-of select="'foot-'"/>
<xsl:number count="p[@type='Foot' or @type='End']" level="any"/>
</xsl:attribute>
<xsl:next-match/>
</xsl:copy>
</xsl:template>
它给了我以下结果
<doc>
<p id="foot-1"><p type="Foot">
<link ref="http://www.facebook.com">
<c type="Hyperlink">www.facebook.com</c>
</link>
</p></p>
<p id="foot-2"><p type="End">
<link ref="http://www.google.com">
<c type="Hyperlink">www.google.com.com</c>
</link>
</p></p>
</doc>
如上结果 xml,它添加了重复的
节点并添加了新属性。但我需要的是这个,
<doc>
<p id="foot-1 type="Foot">
<link ref="http://www.facebook.com">
<c type="Hyperlink">www.facebook.com</c>
</link>
</p></p>
<p id="foot-2 type="End">
<link ref="http://www.google.com">
<c type="Hyperlink">www.google.com.com</c>
</link>
</p></p>
</doc>
如何通过更改 mu xsl 获得此输出?
我认为您的问题很可能是我们无法从您的问题中看出的 - 您正在调用 xsl:next-match
,在一个模板中,该模板已经从 xsl:copy
指令。如果下一场比赛,无论碰巧是什么,xsl:copy
,你都会在第一个标签中得到第二个 p
标签,就像你看到的那样。
听起来您需要做的是拥有另一个具有更高优先级且仅匹配 p
的模板,执行 <xsl:copy>
,在其中调用 <xsl:next-match>
然后处理子节点, 并从匹配特定案例的低优先级模板中删除 <xsl:copy>
。
<xsl:template match="p" priority="2">
<xsl:copy>
<xsl:next-match/>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="p[@type='Foot']" priority="1">
<xsl:attribute name="id">
<xsl:value-of select="'foot-'"/>
<xsl:number count="p[@type='Foot' or @type='End']" level="any"/>
</xsl:attribute>
<xsl:next-match/>
</xsl:template>
etc..
顺便说一下,您不需要 <xsl:value-of select="'foot-'"/>
- 如果它只是一个常量,那么 <xsl:text>foot-</xsl:text>
就可以了。