Reputation: 1020
I have xml like follows,
<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>
what I need to do is add dynamic id attributes to <p>
node which has attribute "Foot"
and "End"
. SO I have written following 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>
it gives me following result
<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>
as above result xml, it add duplicate
node and add new attribute. but what I need is this,
<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>
How can I get this output from changing mu xsl?
Upvotes: 0
Views: 456
Reputation: 12075
I think your problem is likely to be something we can't see from your question- you're calling xsl:next-match
, in a template that's already outputting a p
tag from the xsl:copy
instruction. If the next match, whatever that happens to be also does xsl:copy
, you're going to get a second p
tag inside the first, like you're seeing.
It sounds like what you need to do is have another template with higher priority that matches only p
, have this do the <xsl:copy>
, call <xsl:next-match>
inside that then process subnodes, and remove the <xsl:copy>
from the lower-priority templates that match specific cases.
<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..
Incidentally, you don't need <xsl:value-of select="'foot-'"/>
- if it's just a constant, then <xsl:text>foot-</xsl:text>
will do.
Upvotes: 3