Reputation: 83
My Input XML is like as,
<section counter="yes" level="2">
<title>Course of Illness Following Stroke(<link idref="c003_f001">Fig. 3.1</link>)</title>
<section counter="yes" level="3">
Output should be,
<section counter="yes" level="2">
<title>Course of Illness Following Stroke</title>
<para><link idref="c003_f001">(Fig. 3.1)</link></para>
<section counter="yes" level="3">
Whenever the link is appearing within 'title' with parenthesis'()' then it should be moved to next para. If 'para' is not appeared then we should create and move the entire 'link' with parenthesis'()'.
I have wrote the XSLT but it's not given the desired output.
<xsl:template match="title/text()">
<xsl:if test="matches(., '\(') and following::node()[self::link]">
<para>
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</para>
</xsl:if>
<xsl:if test="matches(., '\)') and following::node()[self::link]">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
Could you please guide us to resolve this issue.
Upvotes: 1
Views: 59
Reputation: 1458
It does not make much sense to use xsl:apply-templates
within a template that matches a text node. (And another issue: You do not really require matches()
, as you do not need a regular expression to search for single round brackets; instead, contains()
would be sufficient.)
A procedure for your scenario could works like this: Look for title
that contains link
surrounded by brackets (combining *-sibling::
and substring-*()
). You can do that completely with XPath. In matching elements you just recompose the title, starting with copying title
and filling it with all text before (
. It could be neccessary to adjust this, depending on the possible content of title: Maybe it can contain other elements preceding to link
(let us know if that is the case). After that, just insert a copy of link
into a para
. And that's it.
<xsl:template
match="title[link[ends-with(preceding-sibling::text(), '(') and starts-with(following-sibling::text(), ')')]]">
<xsl:copy>
<xsl:value-of select="substring-before(text()[1], '(')"/>
</xsl:copy>
<para>
<!-- edit -->
<!--<xsl:copy-of select="link"/>-->
<xsl:apply-templates mode="parenthesize" select="link"/>
<!-- end edit -->
</para>
</xsl:template>
<!-- edit: new template -->
<xsl:template match="link" mode="parenthesize">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:text>(</xsl:text>
<xsl:apply-templates/>
<xsl:text>)</xsl:text>
</xsl:copy>
</xsl:template>
PS. I assume that you use identity transform for all other elements.
Upvotes: 1