Reputation: 1020
I have a xsl like follows,
<doc>
<sec>
<para>para</para>
<para>para</para>
<para>§ 9.02A spara</para>
<para>para</para>
<para>para</para>
</sec>
<sec>
<para>para</para>
<para>para</para>
<para>para</para>
<para>para</para>
<para>para</para>
</sec>
<sec>
<para>para</para>
<para>para</para>
<para>para</para>
<para>para</para>
<para>para</para>
</sec>
</doc>
I need to add a attribute name type
to <para>
element by analyzing text()
node of the <para>
element.
if text()
node starting with '§ 9.02A' the type attribute should be 'xxx' otherwise the type attribute should be sequential number value starting from number 1 for each level, so expected output should be,
<doc>
<sec>
<para type="1">para</para>
<para type="2">para</para>
<para type="XXX">§ 9.02A spara</para>
<para type="3">para</para>
<para type="4">para</para>
</sec>
<sec>
<para type="1">para</para>
<para type="2">para</para>
<para type="3">para</para>
<para type="4">para</para>
<para type="5">para</para>
</sec>
<sec>
<para type="1">para</para>
<para type="2">para</para>
<para type="3">para</para>
<para type="4">para</para>
<para type="5">para</para>
</sec>
</doc>
I have written xsl for do this as follows,
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="para">
<xsl:variable name="position" as="xs:string">
<xsl:number count="para" level="single" select=". except para[matches(.,'§\s\d+\.\d+[A-Z]')]"/>
</xsl:variable>
<para>
<xsl:if test="matches(.,'§\s\d+\.\d+[A-Z]')">
<xsl:attribute name="type">
<xsl:value-of select="'XXX'"/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:if>
<xsl:if test="not(matches(.,'§\s\d+\.\d+[A-Z]'))">
<xsl:attribute name="type">
<xsl:value-of select="$position"/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:if>
</para>
</xsl:template>
problem here is, when the text() is starting from '§ 9.02A'
the attribute is not skiping that level, (see the level one <para>
of generated output.. current values are 1,2,XXX,4,5. it should be 1,2,XXX,3,4)
current output,
<doc>
<sec>
<para type="1">para</para>
<para type="2">para</para>
<para type="XXX">§ 9.02A spara</para>
<para type="4">para</para>
<para type="5">para</para>
</sec>
<sec>
<para type="1">para</para>
<para type="2">para</para>
<para type="3">para</para>
<para type="4">para</para>
<para type="5">para</para>
</sec>
<sec>
<para type="1">para</para>
<para type="2">para</para>
<para type="3">para</para>
<para type="4">para</para>
<para type="5">para</para>
</sec>
</doc>
this can be done by using other method like count() function, but I really needed to do this in this way. can any one suggest me a method how can I do modified to get the correct output?
Upvotes: 1
Views: 415
Reputation: 7173
change
<xsl:number count="para" level="single" select=". except para[matches(.,'§\s\d+\.\d+[A-Z]')]"/>
to
<xsl:number count="para[not(matches(.,'§\s\d+\.\d+[A-Z]+'))]" level="single"/>
Upvotes: 3