Tuesday, 27 August 2013

Use xsl:number and match the substring of current element's attribute with the first instance of preceding sibling attribute substring?

Use xsl:number and match the substring of current element's attribute with
the first instance of preceding sibling attribute substring?

How do I use xsl:number to match the substring of a current element's
attribute with the first instance of preceding sibling attribute's
substring?
If you look at the Source XML file below, when the substring (characters 1
- 5) of a bookDocument's pages attribute is repeated in further
bookDocuments I intend to insert a letter value (starting with "a") into
the output file's doc_code attribute for each subsequent bookDocument
whose pages attribute substring 1- 5 matches the first. I've been trying
to acheive the desired result using xsl:number but have been unsuccessful
using both the "from" and "count" features of xsl:number. See the doc_code
attribute for the result file resultdoc_5_12351.xml as an example of the
incorrect output. Any helpful advise as to what I'm doing wrong would be
greatly appreciated.
The Source XML file:
<book>
<bookGlossary>
<para>Here is a glossary.</para>
</bookGlossary>
<bookPart>
<bookChapter>
<title>Chapter 1</title>
<bookDocument docnum='1' pages="12345,12346">
<para>This is the newDoc that should output a doc_code of 12345</para>
</bookDocument>
<bookDocument docnum='2' pages="12346,12347,12348,12349,12350">
<para>This is the newDoc that should output a doc_code of 12346</para>
</bookDocument>
<bookDocument docnum='3' pages="12350,12351">
<para>This is the newDoc that should output a doc_code of 12350</para>
</bookDocument>
<bookDocument docnum='4' pages="12351">
<para>This is the newDoc that should output a doc_code of 12351</para>
</bookDocument>
<bookDocument docnum='5' pages="12351">
<para>This is the newDoc that should output a doc_code of 12351a</para>
</bookDocument>
<bookDocument docnum='6' pages="12351,12352">
<para>This is the newDoc that should output a doc_code of 12351b</para>
</bookDocument>
<bookDocument docnum='7' pages="12353">
<para>This is the newDoc that should output a doc_code of 12353</para>
</bookDocument>
<bookDocument docnum='8' pages="12353">
<para>This is the newDoc that should output a doc_code of 12353a</para>
</bookDocument>
<bookDocument docnum='9' pages="12354">
<para>This is the newDoc that should output a doc_code of 12354</para>
</bookDocument>
<bookDocument docnum='10' pages="12354, 12355">
<para>This is the newDoc that should output a doc_code of 12354a</para>
</bookDocument>
<bookDocument docnum='11' pages="12355">
<para>This is the newDoc that should output a doc_code of 12355</para>
</bookDocument>
<bookDocument docnum='12' pages="12355">
<para>This is the newDoc that should output a doc_code of 12355a</para>
</bookDocument>
<bookDocument docnum='13' pages="12356">
<para>This is the newDoc that should output a doc_code of 12356</para>
</bookDocument>
</bookChapter>
</bookPart>
</book>
My current XSLT:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" omit-xml-declaration="yes"
indent="yes" encoding="UTF-8"/>
<xsl:template match="/book">
<xsl:for-each select="bookPart/bookChapter/bookDocument">
<xsl:result-document href="resultdoc_{@docnum}_{@pages/substring(., 1,
5)}.xml">
<newDoc>
<docStart>
<xsl:attribute name="doc_code">
<xsl:choose>
<xsl:when test="preceding-sibling::bookDocument/@pages/substring(., 1, 5)
= current()/@pages/substring(., 1, 5)">
<xsl:value-of select="@pages/substring(., 1, 5)"/>
<xsl:number level="any"
from="bookDocument[preceding-sibling::bookDocument[@pages/substring(., 1,
5) = current()/@pages/substring(., 1, 5)]]" format="a"/></xsl:when>
<xsl:otherwise><xsl:value-of select="@pages/substring(., 1, 5) "/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</docStart>
<docBody>
<xsl:apply-templates select="*|text()"/>
</docBody>
</newDoc>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
<xsl:template match="*|@*|text()">
<xsl:copy>
<xsl:apply-templates select="*|@*|text()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:if test="normalize-space(.)">
<xsl:value-of select="normalize-space(.)"/>
</xsl:if>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
The result documents with incorrect doc_code attribute values:
<!--resultdoc_1_12345.xml-->
<newDoc>
<docStart doc_code="12345"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12345</para>
</docBody>
</newDoc>
<!--resultdoc_2_12346.xml-->
<newDoc>
<docStart doc_code="12346"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12346</para>
</docBody>
</newDoc>
<!--resultdoc_3_12350.xml-->
<newDoc>
<docStart doc_code="12350"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12350</para>
</docBody>
</newDoc>
<!--resultdoc_4_12351.xml-->
<newDoc>
<docStart doc_code="12351"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12351</para>
</docBody>
</newDoc>
<!--resultdoc_5_12351.xml-->
<newDoc>
<docStart doc_code="12351e"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12351a</para>
</docBody>
</newDoc>
<!--resultdoc_6_12351.xml-->
<newDoc>
<docStart doc_code="12351b"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12351b</para>
</docBody>
</newDoc>
<!--resultdoc_7_12353.xml-->
<newDoc>
<docStart doc_code="12353"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12353</para>
</docBody>
</newDoc>
<!--resultdoc_8_12353.xml-->
<newDoc>
<docStart doc_code="12353c"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12353a</para>
</docBody>
</newDoc>
<!--resultdoc_9_12354.xml-->
<newDoc>
<docStart doc_code="12354"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12354</para>
</docBody>
</newDoc>
<!--resultdoc_10_12354.xml-->
<newDoc>
<docStart doc_code="12354c"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12354a</para>
</docBody>
</newDoc>
<!--resultdoc_11_12355.xml-->
<newDoc>
<docStart doc_code="12355"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12355</para>
</docBody>
</newDoc>
<!--resultdoc_12_12355.xml-->
<newDoc>
<docStart doc_code="12355c"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12355a</para>
</docBody>
</newDoc>
<!--resultdoc_13_12356.xml-->
<newDoc>
<docStart doc_code="12356"/>
<docBody>
<para>This is the newDoc that should output a doc_code of 12356</para>
</docBody>
</newDoc>

No comments:

Post a Comment