Reputation: 3
Logic :
<lpage>
content with the <fpage>
content to generate the content for the CXML, only the differing numbers should be included. For example, in the code sample, the <fpage>
element is 1545
and the <lpage>
element is 1547
, making only the final digit (7) different, so the resulting content should be 1545–7
. However, if the <lpage>
content was 1557
, then the result would be 1545–57
.Input :
<doc>
<year>2007</year>;
<volume>26</volume>:
<fpage>1545</fpage>-
<lpage>1547</lpage>
</doc>
Output should be :
<p>2007;26(6):1545-7.</p
I have no idea to compare those numbers and getting the desired output.
Upvotes: 0
Views: 64
Reputation: 850
Please Use This Code
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:output method="xml" omit-xml-declaration="no" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="fpagelenght" select="string-length(doc/fpage)"/>
<xsl:variable name="lpagelenght" select="string-length(doc/lpage)"/>
<xsl:variable name="vollenght" select="string-length(doc/volume)"/>
<xsl:variable name="match1" select="number(substring(doc/fpage, 1, 1))"/>
<xsl:variable name="match2" select="number(substring(doc/lpage, 1, 1))"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//text()">
<xsl:value-of select="normalize-space(.)"/>
</xsl:template>
<xsl:template match="doc">
<p>
<xsl:apply-templates/>
</p>
</xsl:template>
<xsl:template match="year | fpage">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="volume">
<xsl:apply-templates/>
<xsl:if test="$vollenght > 1">
<xsl:text>(</xsl:text>
<xsl:value-of select="substring(., $vollenght)"/>
<xsl:text>)</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="lpage">
<xsl:choose>
<xsl:when test="$match2 = $match1">
<xsl:choose>
<xsl:when test="$lpagelenght = 2 and $fpagelenght = 2">
<xsl:value-of select="substring(., $lpagelenght - 1)"/>
</xsl:when>
<xsl:when test="$lpagelenght = 3 and $fpagelenght = 3">
<xsl:value-of select="number(substring(., $lpagelenght - 1))"/>
</xsl:when>
<xsl:when test="$lpagelenght = 4 and $fpagelenght = 4">
<xsl:value-of select="number(substring(., $lpagelenght - 1))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Reputation: 31011
One of possible solutions, using XSLT 2.0:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:my="dummy" exclude-result-prefixes="my xs">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:function name="my:lastPage">
<xsl:param name="s1" as="xs:string"/>
<xsl:param name="s2" as="xs:string"/>
<xsl:variable name="l1" select="string-length($s1)"/>
<xsl:variable name="l2" select="string-length($s2)"/>
<xsl:for-each select="1 to $l2">
<xsl:if test="$l1 lt $l2 or substring($s1, 1, .) != substring($s2, 1, .)">
<xsl:value-of select="substring($s2, ., 1)"/>
</xsl:if>
</xsl:for-each>
</xsl:function>
<xsl:template match="doc">
<p><xsl:value-of select="concat(year, ';', volume, '(6):', fpage, '-')"/>
<xsl:value-of select="my:lastPage(fpage, lpage)"/>
</p>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
</xsl:stylesheet>
The main part of this solution is a function (lastPage), with 2 arguments (fpage and lpage). It loops over chars in lpage and includes the current char in the result if:
Upvotes: 1