Userforxslt
Userforxslt

Reputation: 3

Analyzing the number in xslt

Logic :

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

Answers (2)

Sam
Sam

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 &gt; 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

Valdi_Bo
Valdi_Bo

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:

  • either fpage is shorter than lpage (e.g. 100 and 1000),
  • or the substring of lpage up to the current char is different than the corresponding substring of fpage.

Upvotes: 1

Related Questions