Reputation: 3897
I have some XML like so:
<subsection number="5">
<p>
(5) The <link path="123">Secretary of State</link> shall appoint such as....
</p>
</subsection>
I can't change the XML and I need to strip out the (5) at the start of the paragraph and use the number attribute in the parent tag to create a new paragraph number with appropriate markup:
<xsl:template match="subsection/p">
<xsl:variable name="number">
<xsl:text>(</xsl:text>
<xsl:value-of select="../@number"/>
<xsl:text>)</xsl:text>
</xsl:variable>
<xsl:variable name="copy">
<xsl:value-of select="."/>
</xsl:variable>
<p>
<span class="indent">
<xsl:value-of select="$number" />
</span>
<span class="copy">
<xsl:value-of select="substring-after($copy, $number)" />
</span>
</p>
</xsl:template>
The problem is the rest of the paragraph may contain more XML that needs to be transformed, such as the link tag in the example.
I don't know how to apply templates to this once I've used the substring-after function.
Upvotes: 2
Views: 711
Reputation: 60424
An explicit approach is to handle the first text child of subsection/p
elements separately from all other children. For demonstration purposes, I've also added a template for converting link
elements into a
elements.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="subsection/p/text()[1]">
<xsl:value-of select="concat('(', ../../@number, ')')"/>
</xsl:template>
<xsl:template match="subsection/p">
<p>
<span class="indent">
<xsl:apply-templates select="text()[1]"/>
</span>
<span class="copy">
<xsl:apply-templates select="*|text()[not(position()=1)]"/>
</span>
</p>
</xsl:template>
<xsl:template match="subsection/p/link">
<a href="{@path}"><xsl:value-of select="."/></a>
</xsl:template>
</xsl:stylesheet>
This stylesheet produces the following output:
<p><span class="indent">(5)</span><span class="copy">
<a href="123">Secretary of State</a>shall appoint such as....</span></p>
Upvotes: 1