Limiting output (XSLT 2.0 Temporary Tree) - xslt-2.0

A co-worker and I have been given a new requirement. Please review the following.
We have a requirement to transform an XML source document while enforcing a numerical limit on certain items in the result document. A source document, an XSLT stylesheet, and a result document are reproduced below. This result document, however, does not reflect the desired numerical limit, because this stylesheet transforms the source document without any restriction.
At the end, our question will be: How can the desired numerical limit be enforced in the stylesheet?
Source document:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<T:Message xmlns="http://www.noname.com/Platform" xmlns:T="http://www.noname.com/Transportation">
<T:ShipmentListMessage>
<Shipment>
<ShipmentNumber>ABC</ShipmentNumber>
<PickupCommodityCode>Hazmat</PickupCommodityCode>
<DeliveryCommodityCode>Hazmat</DeliveryCommodityCode>
<ShipmentLine>
<ShipmentLineNumber>ABC-1</ShipmentLineNumber>
<OrderLineItemNumber>1</OrderLineItemNumber>
</ShipmentLine>
<ShipmentLine>
<ShipmentLineNumber>ABC-2</ShipmentLineNumber>
<OrderLineItemNumber>2</OrderLineItemNumber>
</ShipmentLine>
<ShipmentLine>
<ShipmentLineNumber>ABC-3</ShipmentLineNumber>
<OrderLineItemNumber>3</OrderLineItemNumber>
</ShipmentLine>
</Shipment>
<Shipment>
<ShipmentNumber>DEF</ShipmentNumber>
<PickupCommodityCode>Hazmat</PickupCommodityCode>
<DeliveryCommodityCode>Hazmat</DeliveryCommodityCode>
<ShipmentLine>
<ShipmentLineNumber>DEF-1</ShipmentLineNumber>
<OrderLineItemNumber>1</OrderLineItemNumber>
</ShipmentLine>
<ShipmentLine>
<ShipmentLineNumber>DEF-2</ShipmentLineNumber>
<OrderLineItemNumber>2</OrderLineItemNumber>
</ShipmentLine>
</Shipment>
<Shipment>
<ShipmentNumber>GHI</ShipmentNumber>
<PickupCommodityCode>Hazmat</PickupCommodityCode>
<DeliveryCommodityCode>Hazmat</DeliveryCommodityCode>
<ShipmentLine>
<ShipmentLineNumber>GHI-1</ShipmentLineNumber>
<OrderLineItemNumber>1</OrderLineItemNumber>
</ShipmentLine>
<ShipmentLine>
<ShipmentLineNumber>GHI-2</ShipmentLineNumber>
<OrderLineItemNumber>2</OrderLineItemNumber>
</ShipmentLine>
<ShipmentLine>
<ShipmentLineNumber>GHI-3</ShipmentLineNumber>
<OrderLineItemNumber>3</OrderLineItemNumber>
</ShipmentLine>
<ShipmentLine>
<ShipmentLineNumber>GHI-4</ShipmentLineNumber>
<OrderLineItemNumber>4</OrderLineItemNumber>
</ShipmentLine>
</Shipment>
</T:ShipmentListMessage>
<T:MovementListMessage>
<Movement>
<MovementStop>
<StopSequenceNumber>0</StopSequenceNumber>
<MovementStopLine>
<OperationType>Pickup</OperationType>
<ShipmentNumber>ABC</ShipmentNumber>
</MovementStopLine>
<MovementStopLine>
<OperationType>Pickup</OperationType>
<ShipmentNumber>DEF</ShipmentNumber>
</MovementStopLine>
<MovementStopLine>
<OperationType>Pickup</OperationType>
<ShipmentNumber>GHI</ShipmentNumber>
</MovementStopLine>
</MovementStop>
<MovementStop>
<StopSequenceNumber>1</StopSequenceNumber>
<MovementStopLine>
<OperationType>Deliver</OperationType>
<ShipmentNumber>ABC</ShipmentNumber>
</MovementStopLine>
</MovementStop>
<MovementStop>
<StopSequenceNumber>2</StopSequenceNumber>
<MovementStopLine>
<OperationType>Deliver</OperationType>
<ShipmentNumber>DEF</ShipmentNumber>
</MovementStopLine>
<MovementStopLine>
<OperationType>Deliver</OperationType>
<ShipmentNumber>GHI</ShipmentNumber>
</MovementStopLine>
</MovementStop>
</Movement>
</T:MovementListMessage>
</T:Message>
XSLT Stylesheet:
<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:t="http://www.noname.com/Transportation" xmlns:vc="http://www.noname.com/Platform">
<xsl:output method="text" indent="no"/>
<xsl:template match="t:Message">
<xsl:variable name="shipmentPath" select="t:ShipmentListMessage/vc:Shipment"/>
<xsl:variable name="movementPath" select="t:MovementListMessage/vc:Movement"/>
<xsl:variable name="numDeliverLocations" select="count($movementPath/vc:MovementStop/vc:MovementStopLine[vc:OperationType = 'Deliver'])"/>
<xsl:variable name="numOffers" select="count($shipmentPath)"/>
<xsl:for-each select="$movementPath/vc:MovementStop">
<xsl:for-each select="vc:MovementStopLine[vc:OperationType = 'Deliver']">
<xsl:variable name="OfferNumber" select="vc:ShipmentNumber"/>
<xsl:variable name="OfferCount" select="count(../vc:MovementStopLine[vc:OperationType = 'Deliver'])"/>
<xsl:if test="position() = 1">
S5*<xsl:value-of select="../vc:StopSequenceNumber+1"/>*UL<xsl:text>~</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="vc:MovementStopLine[vc:OperationType = 'Deliver']">
<xsl:variable name="OfferNumber" select="vc:ShipmentNumber"/>
<xsl:variable name="OfferCount" select="count(../vc:MovementStopLine[vc:OperationType = 'Deliver'])"/>
<xsl:variable name="OfferPosition" select="if (position() lt 10) then position() else 0"/>
<xsl:for-each select="$shipmentPath[vc:ShipmentNumber = $OfferNumber and vc:DeliveryCommodityCode != '']">
<xsl:choose>
<xsl:when test="vc:DeliveryCommodityCode = 'Hazmat'">
<xsl:if test="$numOffers gt 1 or $numDeliverLocations = 1">
<xsl:for-each select="vc:ShipmentLine">
<xsl:variable name="ShipmentLine" select="vc:ShipmentLineNumber"/>
<xsl:choose>
<xsl:when test="$OfferCount eq 1">
L5*<xsl:value-of select="vc:OrderLineItemNumber"/><xsl:text>~</xsl:text>
</xsl:when>
<xsl:when test="position() lt 10">
L5*<xsl:value-of select="concat($OfferPosition, '0', vc:OrderLineItemNumber)"/><xsl:text>~</xsl:text>
</xsl:when>
<xsl:otherwise>
L5*<xsl:value-of select="concat($OfferPosition, vc:OrderLineItemNumber)"/><xsl:text>~</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:if>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
<xsl:for-each select="vc:MovementStopLine[vc:OperationType = 'Pickup']">
<xsl:variable name="OfferNumber" select="vc:ShipmentNumber"/>
<xsl:variable name="OfferCount" select="count(../vc:MovementStopLine[vc:OperationType = 'Pickup'])"/>
<xsl:if test="position() = 1">
S5*<xsl:value-of select="../vc:StopSequenceNumber+1"/>*LD<xsl:text>~</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="vc:MovementStopLine[vc:OperationType = 'Pickup']">
<xsl:variable name="OfferNumber" select="vc:ShipmentNumber"/>
<xsl:variable name="OfferCount" select="count(../vc:MovementStopLine[vc:OperationType = 'Pickup'])"/>
<xsl:variable name="OfferPosition" select="if (position() lt 10) then position() else 0"/>
<xsl:for-each select="$shipmentPath[vc:ShipmentNumber = $OfferNumber and vc:PickupCommodityCode != '']">
<xsl:choose>
<xsl:when test="vc:PickupCommodityCode = 'Hazmat'">
<xsl:for-each select="vc:ShipmentLine">
<xsl:variable name="ShipmentLine" select="vc:ShipmentLineNumber"/>
<xsl:choose>
<xsl:when test="$OfferCount eq 1">
L5*<xsl:value-of select="vc:OrderLineItemNumber"/><xsl:text>~</xsl:text>
</xsl:when>
<xsl:when test="position() lt 10">
L5*<xsl:value-of select="concat($OfferPosition, '0', vc:OrderLineItemNumber)"/><xsl:text>~</xsl:text>
</xsl:when>
<xsl:otherwise>
L5*<xsl:value-of select="concat($OfferPosition, vc:OrderLineItemNumber)"/><xsl:text>~</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Result document:
S5*1*LD~
L5*101~
L5*102~
L5*103~
L5*201~
L5*202~
L5*301~
L5*302~
L5*303~
L5*304~
S5*2*UL~
L5*1~
L5*2~
L5*3~
S5*3*UL~
L5*101~
L5*102~
L5*201~
L5*202~
L5*203~
L5*204~
In order to satisfy our requirement, the numerical limit must somehow be built into the stylesheet. For the purpose of this discussion, the desired limit is 5 on the number of “L5” segments following an “S5” segment. In this example, the limit will reduce the number of “L5” segments to 5 each following “S5*1*LD” and “S5*3*UL”. The limit will not come into play in the case of “S5*2*UL”.
Desired result document with the “L5” limit applied:
S5*1*LD~
L5*101~
L5*102~
L5*103~
L5*201~
L5*202~
S5*2*UL~
L5*1~
L5*2~
L5*3~
S5*3*UL~
L5*101~
L5*102~
L5*201~
L5*202~
L5*203~
Again, our question is: How can the desired numerical limit be coded in the stylesheet?

I think you could store the first result in a variable and then group and count as needed, for easier processing I have chosen to wrap the intermediary result as XML:
<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:t="http://www.noname.com/Transportation" xmlns:vc="http://www.noname.com/Platform"
exclude-result-prefixes="t vc">
<xsl:output method="text"/>
<xsl:template match="t:Message">
<xsl:variable name="shipmentPath" select="t:ShipmentListMessage/vc:Shipment"/>
<xsl:variable name="movementPath" select="t:MovementListMessage/vc:Movement"/>
<xsl:variable name="numDeliverLocations" select="count($movementPath/vc:MovementStop/vc:MovementStopLine[vc:OperationType = 'Deliver'])"/>
<xsl:variable name="numOffers" select="count($shipmentPath)"/>
<xsl:variable name="items">
<xsl:for-each select="$movementPath/vc:MovementStop">
<xsl:for-each select="vc:MovementStopLine[vc:OperationType = 'Deliver']">
<xsl:variable name="OfferNumber" select="vc:ShipmentNumber"/>
<xsl:variable name="OfferCount" select="count(../vc:MovementStopLine[vc:OperationType = 'Deliver'])"/>
<xsl:if test="position() = 1">
<item>S5*<xsl:value-of select="../vc:StopSequenceNumber+1"/>*UL<xsl:text>~</xsl:text></item>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="vc:MovementStopLine[vc:OperationType = 'Deliver']">
<xsl:variable name="OfferNumber" select="vc:ShipmentNumber"/>
<xsl:variable name="OfferCount" select="count(../vc:MovementStopLine[vc:OperationType = 'Deliver'])"/>
<xsl:variable name="OfferPosition" select="if (position() lt 10) then position() else 0"/>
<xsl:for-each select="$shipmentPath[vc:ShipmentNumber = $OfferNumber and vc:DeliveryCommodityCode != '']">
<xsl:choose>
<xsl:when test="vc:DeliveryCommodityCode = 'Hazmat'">
<xsl:if test="$numOffers gt 1 or $numDeliverLocations = 1">
<xsl:for-each select="vc:ShipmentLine">
<xsl:variable name="ShipmentLine" select="vc:ShipmentLineNumber"/>
<xsl:choose>
<xsl:when test="$OfferCount eq 1">
<item>L5*<xsl:value-of select="vc:OrderLineItemNumber"/><xsl:text>~</xsl:text></item>
</xsl:when>
<xsl:when test="position() lt 10">
<item>L5*<xsl:value-of select="concat($OfferPosition, '0', vc:OrderLineItemNumber)"/><xsl:text>~</xsl:text></item>
</xsl:when>
<xsl:otherwise>
<item>L5*<xsl:value-of select="concat($OfferPosition, vc:OrderLineItemNumber)"/><xsl:text>~</xsl:text></item>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:if>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
<xsl:for-each select="vc:MovementStopLine[vc:OperationType = 'Pickup']">
<xsl:variable name="OfferNumber" select="vc:ShipmentNumber"/>
<xsl:variable name="OfferCount" select="count(../vc:MovementStopLine[vc:OperationType = 'Pickup'])"/>
<xsl:if test="position() = 1">
<item>S5*<xsl:value-of select="../vc:StopSequenceNumber+1"/>*LD<xsl:text>~</xsl:text></item>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="vc:MovementStopLine[vc:OperationType = 'Pickup']">
<xsl:variable name="OfferNumber" select="vc:ShipmentNumber"/>
<xsl:variable name="OfferCount" select="count(../vc:MovementStopLine[vc:OperationType = 'Pickup'])"/>
<xsl:variable name="OfferPosition" select="if (position() lt 10) then position() else 0"/>
<xsl:for-each select="$shipmentPath[vc:ShipmentNumber = $OfferNumber and vc:PickupCommodityCode != '']">
<xsl:choose>
<xsl:when test="vc:PickupCommodityCode = 'Hazmat'">
<xsl:for-each select="vc:ShipmentLine">
<xsl:variable name="ShipmentLine" select="vc:ShipmentLineNumber"/>
<xsl:choose>
<xsl:when test="$OfferCount eq 1">
<item>L5*<xsl:value-of select="vc:OrderLineItemNumber"/><xsl:text>~</xsl:text></item>
</xsl:when>
<xsl:when test="position() lt 10">
<item>L5*<xsl:value-of select="concat($OfferPosition, '0', vc:OrderLineItemNumber)"/><xsl:text>~</xsl:text></item>
</xsl:when>
<xsl:otherwise>
<item>L5*<xsl:value-of select="concat($OfferPosition, vc:OrderLineItemNumber)"/><xsl:text>~</xsl:text></item>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
<xsl:for-each-group select="$items/item" group-starting-with="item[starts-with(., 'S5*')]">
<xsl:if test="position() gt 1"><xsl:text>
</xsl:text></xsl:if>
<xsl:value-of select="if (starts-with(., 'S5*1*LD') or starts-with(., 'S5*3*UL'))
then current-group()[position() le 6] else current-group()"
separator="
"/>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
With that stylesheet and your input Saxon 9.5 outputs
S5*1*LD~
L5*101~
L5*102~
L5*103~
L5*201~
L5*202~
S5*2*UL~
L5*1~
L5*2~
L5*3~
S5*3*UL~
L5*101~
L5*102~
L5*201~
L5*202~
L5*203~

Related

Find and replace for the particular texts within same text() node, more than once

Please suggest to find replace the required text within one text() node, some times find-replace text repeated more than once.
Here, scripts should exclue the element '<p>'. Working fine when 'find' text occuring only once in a text node, if it occures more than once, then skipping the replace process (see first <p1>). Please suggest.
XML:
<article>
<p1>The text 1111, 2222, 3333 and 4444 are some values, 1111 another occurance.</p1>
<p1>The text 1111, 2222, 3333 and 4444 are some values</p1>
<p>The text 1111, 2222, 3333 and 4444 are some values</p>
<p1>The text aaaaa, bbbbb, ccccc and ddddd are another set of values</p1>
<p1>The text <i>aaaaa</i>, <b>bbbbb</b> and <c>ccccc</c> are in different form</p1>
</article>
XSLT 2.0:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="#*|node()">
<xsl:copy><xsl:apply-templates select="#* | node()"/></xsl:copy>
</xsl:template>
<xsl:template match="*/text()">
<xsl:call-template name="tempFindReplace">
<xsl:with-param name="pText1" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="tempFindReplace">
<xsl:param name="pText1"/>
<xsl:if test="string-length($pText1) > 0">
<xsl:choose>
<xsl:when test="ancestor::p1">
<xsl:choose>
<xsl:when test="contains($pText1, '1111')">
<xsl:value-of select="substring-before($pText1,'1111')"/><xsl:text>Alpha1</xsl:text>
<xsl:call-template name="tempFindReplace"><xsl:with-param name="pText1" select="substring-after($pText1, '1111')"/></xsl:call-template></xsl:when>
<xsl:when test="contains($pText1, '2222')">
<xsl:value-of select="substring-before($pText1,'2222')"/><xsl:text>Alpha2</xsl:text>
<xsl:call-template name="tempFindReplace"><xsl:with-param name="pText1" select="substring-after($pText1, '2222')"/></xsl:call-template></xsl:when>
<xsl:when test="contains($pText1, '3333')">
<xsl:value-of select="substring-before($pText1,'3333')"/><xsl:text>Alpha3</xsl:text>
<xsl:call-template name="tempFindReplace"><xsl:with-param name="pText1" select="substring-after($pText1, '3333')"/></xsl:call-template></xsl:when>
<xsl:when test="contains($pText1, '4444')">
<xsl:value-of select="substring-before($pText1,'4444')"/><xsl:text>Alpha4</xsl:text>
<xsl:call-template name="tempFindReplace"><xsl:with-param name="pText1" select="substring-after($pText1, '4444')"/></xsl:call-template></xsl:when>
<xsl:when test="contains($pText1, 'aaaaa')">
<xsl:value-of select="substring-before($pText1,'aaaaa')"/><xsl:text>Beta1</xsl:text>
<xsl:call-template name="tempFindReplace"><xsl:with-param name="pText1" select="substring-after($pText1, 'aaaaa')"/></xsl:call-template></xsl:when>
<xsl:when test="contains($pText1, 'bbbbb')">
<xsl:value-of select="substring-before($pText1,'bbbbb')"/><xsl:text>Beta2</xsl:text>
<xsl:call-template name="tempFindReplace"><xsl:with-param name="pText1" select="substring-after($pText1, 'bbbbb')"/></xsl:call-template></xsl:when>
<xsl:when test="contains($pText1, 'ccccc')">
<xsl:value-of select="substring-before($pText1,'ccccc')"/><xsl:text>Beta3</xsl:text>
<xsl:call-template name="tempFindReplace"><xsl:with-param name="pText1" select="substring-after($pText1, 'ccccc')"/></xsl:call-template></xsl:when>
<xsl:when test="contains($pText1, 'ddddd')">
<xsl:value-of select="substring-before($pText1,'ddddd')"/><xsl:text>Beta4</xsl:text>
<xsl:call-template name="tempFindReplace"><xsl:with-param name="pText1" select="substring-after($pText1, 'ddddd')"/></xsl:call-template></xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring($pText1,1,1)"/>
<xsl:call-template name="tempFindReplace">
<xsl:with-param name="pText1" select="substring($pText1, 2)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Required Result:
<article>
<p1>The text Alpha1, Alpha2, Alpha3 and Alpha4 are some values, Alpha1 another occurance.</p1><!-- Alpha1 only replacing, but other texts also required change, I assume here failing because of 1111 appearing twice-->
<p1>The text Alpha1, Alpha2, Alpha3 and Alpha4 are some values</p1>
<p>The text 1111, 2222, 3333 and 4444 are some values</p>
<p1>The text Beta1, Beta2, Beta3 and Beta4 are another set of values</p1>
<p1>The text <i>Beta1</i>, <b>Beta2</b> and <c>Beta3</c> are in different form</p1>
</article>
I continue to think you can use the replace function repeatedly, for instance in XSLT 3 with xsl:iterate:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="replacements" as="array(xs:string)*"
select="['1111', 'Alpha1'], ['2222', 'Alpha2'], ['3333', 'Alpha3'], ['4444', 'Alpha4'],
['aaaaa', 'Beta1'], ['bbbbb', 'Beta2'], ['ccccc', 'Beta3'], ['ddddd', 'Beta4'] "/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="article/*[not(self::p)]//text()">
<xsl:iterate select="$replacements">
<xsl:param name="text" select="."/>
<xsl:on-completion>
<xsl:value-of select="$text"/>
</xsl:on-completion>
<xsl:next-iteration>
<xsl:with-param name="text" select="replace($text, .(1), .(2))"/>
</xsl:next-iteration>
</xsl:iterate>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/bwdwrL
XSLT 2:
called template twice, and got the result.
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="#*|node()">
<xsl:copy><xsl:apply-templates select="#* | node()"/></xsl:copy>
</xsl:template>
<xsl:template match="*[ancestor-or-self::*[matches(name(), '^(p1|p2|p3)$')]]/text()">
<xsl:variable name="var1">
<xsl:call-template name="tempFindReplace">
<xsl:with-param name="pText1" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="tempFindReplace">
<xsl:with-param name="pText1" select="$var1"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="tempFindReplace">
<xsl:param name="pText1"/>
<xsl:if test="string-length($pText1) > 0">
<xsl:choose>
<xsl:when test="contains($pText1, '1111')">
<xsl:value-of select="substring-before($pText1,'1111')"/><xsl:text>Alpha1</xsl:text>
<xsl:call-template name="tempFindReplace"><xsl:with-param name="pText1" select="substring-after($pText1, '1111')"/></xsl:call-template></xsl:when>
<xsl:when test="contains($pText1, '2222')">
<xsl:value-of select="substring-before($pText1,'2222')"/><xsl:text>Alpha2</xsl:text>
<xsl:call-template name="tempFindReplace"><xsl:with-param name="pText1" select="substring-after($pText1, '2222')"/></xsl:call-template></xsl:when>
<xsl:when test="contains($pText1, '3333')">
<xsl:value-of select="substring-before($pText1,'3333')"/><xsl:text>Alpha3</xsl:text>
<xsl:call-template name="tempFindReplace"><xsl:with-param name="pText1" select="substring-after($pText1, '3333')"/></xsl:call-template></xsl:when>
<xsl:when test="contains($pText1, '4444')">
<xsl:value-of select="substring-before($pText1,'4444')"/><xsl:text>Alpha4</xsl:text>
<xsl:call-template name="tempFindReplace"><xsl:with-param name="pText1" select="substring-after($pText1, '4444')"/></xsl:call-template></xsl:when>
<xsl:when test="contains($pText1, 'aaaaa')">
<xsl:value-of select="substring-before($pText1,'aaaaa')"/><xsl:text>Beta1</xsl:text>
<xsl:call-template name="tempFindReplace"><xsl:with-param name="pText1" select="substring-after($pText1, 'aaaaa')"/></xsl:call-template></xsl:when>
<xsl:when test="contains($pText1, 'bbbbb')">
<xsl:value-of select="substring-before($pText1,'bbbbb')"/><xsl:text>Beta2</xsl:text>
<xsl:call-template name="tempFindReplace"><xsl:with-param name="pText1" select="substring-after($pText1, 'bbbbb')"/></xsl:call-template></xsl:when>
<xsl:when test="contains($pText1, 'ccccc')">
<xsl:value-of select="substring-before($pText1,'ccccc')"/><xsl:text>Beta3</xsl:text>
<xsl:call-template name="tempFindReplace"><xsl:with-param name="pText1" select="substring-after($pText1, 'ccccc')"/></xsl:call-template></xsl:when>
<xsl:when test="contains($pText1, 'ddddd')">
<xsl:value-of select="substring-before($pText1,'ddddd')"/><xsl:text>Beta4</xsl:text>
<xsl:call-template name="tempFindReplace"><xsl:with-param name="pText1" select="substring-after($pText1, 'ddddd')"/></xsl:call-template></xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring($pText1,1,1)"/>
<xsl:call-template name="tempFindReplace">
<xsl:with-param name="pText1" select="substring($pText1, 2)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

Roman Numeral to integer value using xslt

Is there any function to convert roman number to integer like format-number function can change integer number to roman number. As i am working on conversion a roman number to integer. if there is no function than i have to handle this in templates.
I have handle this through writing own function, but there is an issue that it is not validate the input value such as (VII or IVII is same) but output is correct.
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:number="http://dummy" version="2.0" >
<xsl:output method="text"/>
<xsl:template match="/">
(<xsl:value-of select="number:RomanToInteger('MMXVII', 0)"/>)
</xsl:template>
<xsl:function name="number:RomanToInteger">
<xsl:param name="romannumber"/>
<xsl:param name="followingvalue"/>
<xsl:choose>
<xsl:when test="ends-with($romannumber,'CM')">
<xsl:value-of select="900 + number:RomanToInteger(substring($romannumber,1,string-length($romannumber)-2), 900)"/>
</xsl:when>
<xsl:when test="ends-with($romannumber,'M')">
<xsl:value-of select="1000+ number:RomanToInteger(substring($romannumber,1,string-length($romannumber)-1), 1000)"/>
</xsl:when>
<xsl:when test="ends-with($romannumber,'CD')">
<xsl:value-of select="400+ number:RomanToInteger(substring($romannumber,1,string-length($romannumber)-2), 400)"/>
</xsl:when>
<xsl:when test="ends-with($romannumber,'D')">
<xsl:value-of select="500+ number:RomanToInteger(substring($romannumber,1,string-length($romannumber)-1), 500)"/>
</xsl:when>
<xsl:when test="ends-with($romannumber,'XC')">
<xsl:value-of select="90+ number:RomanToInteger(substring($romannumber,1,string-length($romannumber)-2), 90)"/>
</xsl:when>
<xsl:when test="ends-with($romannumber,'C')">
<xsl:value-of select="(if(100 ge number($followingvalue)) then 100 else -100)+ number:RomanToInteger(substring($romannumber,1,string-length($romannumber)-1), 100)"/>
</xsl:when>
<xsl:when test="ends-with($romannumber,'XL')">
<xsl:value-of select="40+ number:RomanToInteger(substring($romannumber,1,string-length($romannumber)-2), 40)"/>
</xsl:when>
<xsl:when test="ends-with($romannumber,'L')">
<xsl:value-of select="50+ number:RomanToInteger(substring($romannumber,1,string-length($romannumber)-1), 50)"/>
</xsl:when>
<xsl:when test="ends-with($romannumber,'IX')">
<xsl:value-of select="9+ number:RomanToInteger(substring($romannumber,1,string-length($romannumber)-2), 9)"/>
</xsl:when>
<xsl:when test="ends-with($romannumber,'X')">
<xsl:value-of select="(if(10 ge number($followingvalue)) then 10 else -10) + number:RomanToInteger(substring($romannumber,1,string-length($romannumber)-1), 10)"/>
</xsl:when>
<xsl:when test="ends-with($romannumber,'IV')">
<xsl:value-of select="4+ number:RomanToInteger(substring($romannumber,1,string-length($romannumber)-2), 4)"/>
</xsl:when>
<xsl:when test="ends-with($romannumber,'V')">
<xsl:value-of select="5+ number:RomanToInteger(substring($romannumber,1,string-length($romannumber)-1), 5)"/>
</xsl:when>
<xsl:when test="ends-with($romannumber,'I')">
<xsl:value-of select="(if(1 ge number($followingvalue)) then 1 else -1)+ number:RomanToInteger(substring($romannumber,1,string-length($romannumber)-1), 1)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="0"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
</xsl:stylesheet>

extracting sql data from xml

Let me know your suggestions to extract SQL data from xml. The sample xml would be as below given as input to a procedure as a CLOB:
<filter>
<and>
<or>
<equals field="MARKET_NAME" value="Chicago"/>
<equals field="MARKET_NAME" value="BOSTON"/>
</or>
<or>
<equals field="RANK" value="1"/>
<equals field="RANK" value="2"/>
</or>
<between field="current_data" arg1="start_date" arg2="End_date"/>
<gt field="CUME" value="20"/>
<like field="DMA_NAME" value="%ABC%"/>
</and>
</filter>
The extracted data should look something like this :
(MARKET_NAME = 'Chicago' or MARKET_NAME = 'BOSTON') and
(RANK = 1 or RANK = 2) and
(current_date between start_date and End_Date) and
CUME > 20 and
DMA_NAME like '%ABC%'
Let me know your valuable tips..
Thanks in advance
one approach would be a XSL stylesheet.
but I would add to your XML, datatype. e.g.
<filter>
<and>
<or>
<equals field="MARKET_NAME" value="Chicago" datatype="string"/>
<equals field="MARKET_NAME" value="BOSTON" datatype="string"/>
</or>
<or>
<equals field="RANK" value="1" datatype="number"/>
<equals field="RANK" value="2" datatype="number"/>
</or>
<between field="current_data" arg1="start_date" arg2="End_date" datatype="field"/>
<between field="foo" arg1="20121230" arg2="20130101 01:12:23" datatype="date"/>
<gt field="CUME" value="20" datatype="number"/>
<like field="DMA_NAME" value="%ABC%" datatype="string"/>
</and>
</filter>
then an XSL (this is just a sample. you WILL need to improve this as its just a basic starter for you!)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
exclude-result-prefixes="xd"
version="1.0">
<xsl:output method="text"/>
<xsl:template name="string-replace-all">
<xsl:param name="text"/>
<xsl:param name="replace"/>
<xsl:param name="by"/>
<xsl:choose>
<xsl:when test="contains($text,$replace)">
<xsl:value-of select="substring-before($text,$replace)"/>
<xsl:value-of select="$by"/>
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="substring-after($text,$replace)"/>
<xsl:with-param name="replace" select="$replace"/>
<xsl:with-param name="by" select="$by"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="processDatatype">
<xsl:param name="value" />
<xsl:param name="datatype" />
<xsl:choose>
<xsl:when test="$datatype = 'string'">
<xsl:text>&apos;</xsl:text>
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="$value"/>
<xsl:with-param name="replace" select='"&apos;"'/>
<xsl:with-param name="by" select='"&apos;&apos;"'/>
</xsl:call-template>
<xsl:text>&apos;</xsl:text>
</xsl:when>
<xsl:when test="$datatype = 'date'">
<xsl:text>to_date(&apos;</xsl:text>
<xsl:value-of select="$value"/>
<xsl:text>&apos;,&apos;yyyymmdd hh24:mi:ss&apos;)</xsl:text>
</xsl:when>
<xsl:otherwise><xsl:value-of select="$value"/></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="gt">
<xsl:value-of select="#field"/>
<xsl:text> > </xsl:text>
<xsl:call-template name="processDatatype">
<xsl:with-param name="value"><xsl:value-of select="#value"/></xsl:with-param>
<xsl:with-param name="datatype"><xsl:value-of select="#datatype"/></xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="lt">
<xsl:value-of select="#field"/>
<xsl:text> < </xsl:text>
<xsl:call-template name="processDatatype">
<xsl:with-param name="value"><xsl:value-of select="#value"/></xsl:with-param>
<xsl:with-param name="datatype"><xsl:value-of select="#datatype"/></xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="between">
<xsl:value-of select="#field"/>
<xsl:text> between </xsl:text>
<xsl:call-template name="processDatatype">
<xsl:with-param name="value"><xsl:value-of select="#arg1"/></xsl:with-param>
<xsl:with-param name="datatype"><xsl:value-of select="#datatype"/></xsl:with-param>
</xsl:call-template>
<xsl:text> and </xsl:text>
<xsl:call-template name="processDatatype">
<xsl:with-param name="value"><xsl:value-of select="#arg2"/></xsl:with-param>
<xsl:with-param name="datatype"><xsl:value-of select="#datatype"/></xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="like">
<xsl:value-of select="#field"/>
<xsl:text> like </xsl:text>
<xsl:call-template name="processDatatype">
<xsl:with-param name="value"><xsl:value-of select="#value"/></xsl:with-param>
<xsl:with-param name="datatype"><xsl:value-of select="#datatype"/></xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="equals">
<xsl:value-of select="#field"/>
<xsl:text> = </xsl:text>
<xsl:call-template name="processDatatype">
<xsl:with-param name="value"><xsl:value-of select="#value"/></xsl:with-param>
<xsl:with-param name="datatype"><xsl:value-of select="#datatype"/></xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="and">
<xsl:for-each select="*">
<xsl:if test="position() != 1">
<xsl:text>and </xsl:text>
</xsl:if>
<xsl:choose>
<xsl:when test="name() = 'like'">
<xsl:text>(</xsl:text>
<xsl:call-template name="like" />
<xsl:text>)
</xsl:text>
</xsl:when>
<xsl:when test="name() = 'gt'">
<xsl:text>(</xsl:text>
<xsl:call-template name="gt" />
<xsl:text>)
</xsl:text>
</xsl:when>
<xsl:when test="name() = 'lt'">
<xsl:text>(</xsl:text>
<xsl:call-template name="lt" />
<xsl:text>)
</xsl:text>
</xsl:when>
<xsl:when test="name() = 'equals'">
<xsl:text>(</xsl:text>
<xsl:call-template name="equals" />
<xsl:text>)
</xsl:text>
</xsl:when>
<xsl:when test="name() = 'between'">
<xsl:text>(</xsl:text>
<xsl:call-template name="between" />
<xsl:text>)
</xsl:text>
</xsl:when>
<xsl:when test="name() = 'or'">
<xsl:text>(</xsl:text>
<xsl:call-template name="or" />
<xsl:text>)
</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template name="or">
<xsl:for-each select="*">
<xsl:if test="position() != 1">
<xsl:text>or </xsl:text>
</xsl:if>
<xsl:choose>
<xsl:when test="name() = 'like'">
<xsl:text>(</xsl:text>
<xsl:call-template name="like" />
<xsl:text>)
</xsl:text>
</xsl:when>
<xsl:when test="name() = 'gt'">
<xsl:text>(</xsl:text>
<xsl:call-template name="gt" />
<xsl:text>)
</xsl:text>
</xsl:when>
<xsl:when test="name() = 'lt'">
<xsl:text>(</xsl:text>
<xsl:call-template name="lt" />
<xsl:text>)
</xsl:text>
</xsl:when>
<xsl:when test="name() = 'equals'">
<xsl:text>(</xsl:text>
<xsl:call-template name="equals" />
<xsl:text>)
</xsl:text>
</xsl:when>
<xsl:when test="name() = 'between'">
<xsl:text>(</xsl:text>
<xsl:call-template name="between" />
<xsl:text>)
</xsl:text>
</xsl:when>
<xsl:when test="name() = 'and'">
<xsl:text>(</xsl:text>
<xsl:call-template name="and" />
<xsl:text>)
</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template match="/filter">
<xsl:text>where </xsl:text>
<xsl:for-each select="*">
<xsl:choose>
<xsl:when test="name() = 'and'">
<xsl:call-template name="and" />
</xsl:when>
<xsl:when test="name() = 'or'">
<xsl:call-template name="or" />
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
example:
out XSL stored as an XMLTYPE:
SQL> select * from xsl;
NAME
--------------------
XSL
--------------------------------------------------------------------------------
xml_to_sql
<?xml version="1.0" encoding="WINDOWS-1252"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xd="http:
//www.oxygenxml.com/ns/doc/xsl" exclude-result-prefixes="xd" version="1.0">
<xsl:output method="text"/>
<xsl:template name="string-replace-all">
<xsl:param name="text"/>
...
now we use the transform function of XMLTYPE on the input XML to get the result:
SQL> select dbms_xmlgen.convert(xmltype('<?xml-stylesheet type="text/xsl" href="test.xsl"?>
2 <filter>
3 <and>
4 <or>
5 <equals field="MARKET_NAME" value="Chicago" datatype="string"/>
6 <equals field="MARKET_NAME" value="BOSTON" datatype="string"/>
7 </or>
8 <or>
9 <equals field="RANK" value="1" datatype="number"/>
10 <equals field="RANK" value="2" datatype="number"/>
11 </or>
12 <between field="current_data" arg1="start_date" arg2="End_date" datatype="field"/>
13 <between field="foo" arg1="20121230" arg2="20130101 01:12:23" datatype="date"/>
14 <gt field="CUME" value="20" datatype="number"/>
15 <like field="DMA_NAME" value="%AB&apos;C%" datatype="string"/>
16 </and>
17 </filter>').transform(xsl.xsl).getclobval(), 1)
18 from xsl
19 /
DBMS_XMLGEN.CONVERT(XMLTYPE('<
--------------------------------------------------------------------------------
where ((MARKET_NAME = 'Chicago')
or (MARKET_NAME = 'BOSTON')
)
and ((RANK = 1)
or (RANK = 2)
)
and (current_data between start_date and End_date)
and (foo between to_date('20121230','yyyymmdd hh24:mi:ss') and to_date('20130101
01:12:23','yyyymmdd hh24:mi:ss'))
and (CUME > 20)
and (DMA_NAME like '%AB''C%')

XSLT Wrapping text with multiple tags

I have this span element with a class of autbib-pc-bold-italic
<span class="autbib-pc-bold-italic">autbib</span>
I want to create element tags base on the #class attribute value:
My output should be:
<autbib><pc><bold><italic>autbib</italic></bold></pc></autbib>
Here is my xsl templates:
<xsl:template match="span[contains(#class,'autbib')]">
<xsl:call-template name="pbib.loop">
<xsl:with-param name="count" select="count(tokenize(#class, '-'))"/>
<xsl:with-param name="class" select="tokenize(#class, '-')"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="pbib.loop">
<xsl:param name="index" select="1" />
<xsl:param name="count" select="count(tokenize(#class, '-')) + 1"/>
<xsl:param name="class" select="tokenize(#class, '-')"/>
<xsl:element name="{$class[1]}">
<xsl:if test="not($index = $count)">
<xsl:element name="{$class[$index]}">
<xsl:apply-templates/>
</xsl:element>
</xsl:if>
</xsl:element>
<xsl:if test="not($index = $count)">
<xsl:call-template name="pbib.loop">
<xsl:with-param name="index" select="$index + 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
And have this output which is wrong:
<autbib>
<pc>autbib</pc>
<bold>autbib</bold>
<italic>autbib</italic>
</autbib>
I need to have this output:
<autbib>
<pc>
<bold>
<italic>autbib</italic>
</bold>
</pc>
</autbib>
My problem is that I'm not sure where I should place xsl:apply-template so that tags wrap with each other.
Here is my suggestion:
<xsl:stylesheet
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output indent="yes"/>
<xsl:template match="span[contains(#class,'autbib')]">
<xsl:param name="classes" select="tokenize(#class, '-')"/>
<xsl:choose>
<xsl:when test="not($classes[1])">
<xsl:apply-templates/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{$classes[1]}">
<xsl:apply-templates select=".">
<xsl:with-param name="classes" select="$classes[position() gt 1]"/>
</xsl:apply-templates>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
With Saxon 9.4 that transforms the input
<span class="autbib-pc-bold-italic">autbib</span>
into the result
<autbib>
<pc>
<bold>
<italic>autbib</italic>
</bold>
</pc>
</autbib>

Umbraco outputting filesize

I'm trying to output the correct size for pdf files that has been uploaded.
But the only output is 0 - what am I doing wrong?
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp " "> ]>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" xmlns:umbraco.contour="urn:umbraco.contour"
exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets umbraco.contour ">
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:param name="currentPage"/>
<xsl:variable name="documentTypeAlias" select="string('PdfItem')"/>
<xsl:variable name="size" select="#currentpage/data [#alias = 'umbracoBytes']" />
<xsl:variable name="sizeAndSuffix">
<xsl:choose>
<xsl:when test="$size >= 1073741824">
<xsl:value-of select="format-number($size div 1073741824,'#,###')"/>
<xsl:text>GB</xsl:text>
</xsl:when>
<xsl:when test="$size >= 1048576">
<xsl:value-of select="format-number($size div 1048576,'#,###')"/>
<xsl:text>MB</xsl:text>
</xsl:when>
<xsl:when test="$size >= 1024">
<xsl:value-of select="format-number($size div 1024,'#,###')"/>
<xsl:text>KB</xsl:text>
</xsl:when>
<xsl:when test="$size > 0 and $size < 1024">
<xsl:value-of select="format-number($size div 0,'#,###')"/>
<xsl:text> Bytes</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>0 Bytes</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:template match="/">
<xsl:for-each select="$currentPage/node [#nodeTypeAlias = $documentTypeAlias and string(data [#alias='umbracoNaviHide']) != '0']">
<div class="pdf">
<a>
<xsl:attribute name="class">pdfmenu</xsl:attribute>
<xsl:attribute name="href"><xsl:value-of select="umbraco.library:GetMedia(./data[#alias='pdf'], 0)/data [#alias = 'umbracoFile']"/></xsl:attribute>
<strong><xsl:value-of select="#nodeName"/><span>
(<xsl:value-of select="$sizeAndSuffix"/>)</span></strong>
<em><xsl:value-of select="data [#alias = 'PDFBeskrivelse']"/></em>
<img>
<xsl:attribute name="src"><xsl:value-of select="data [#alias = 'PDFBillede']"/></xsl:attribute>
<xsl:attribute name="alt"></xsl:attribute>
<xsl:attribute name="height">200</xsl:attribute>
<xsl:attribute name="width">141</xsl:attribute>
</img>
</a>
</div>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Alright, I've move the size variable into the for-each loop, as it varies per file and fixed a few typos:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY nbsp " ">
]>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" xmlns:umbraco.contour="urn:umbraco.contour"
exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets umbraco.contour ">
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:param name="currentPage"/>
<xsl:variable name="documentTypeAlias" select="string('PdfItem')"/>
<xsl:template match="/">
<xsl:for-each select="$currentPage/node [#nodeTypeAlias = $documentTypeAlias and string(data [#alias='umbracoNaviHide']) != '0']">
<xsl:if test="string(data [#alias = 'pdf']) != ''">
<xsl:variable name="size" select="umbraco.library:GetMedia(data[#alias='pdf'], 0)/data [#alias = 'umbracoFile']" />
<xsl:variable name="sizeAndSuffix">
<xsl:choose>
<xsl:when test="$size >= 1073741824">
<xsl:value-of select="format-number($size div 1073741824,'#,###')"/>
<xsl:text>GB</xsl:text>
</xsl:when>
<xsl:when test="$size >= 1048576">
<xsl:value-of select="format-number($size div 1048576,'#,###')"/>
<xsl:text>MB</xsl:text>
</xsl:when>
<xsl:when test="$size >= 1024">
<xsl:value-of select="format-number($size div 1024,'#,###')"/>
<xsl:text>KB</xsl:text>
</xsl:when>
<xsl:when test="$size > 0 and $size < 1024">
<xsl:value-of select="format-number($size div 0,'#,###')"/>
<xsl:text> Bytes</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>0 Bytes</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<div class="pdf">
<a>
<xsl:attribute name="class">pdfmenu</xsl:attribute>
<xsl:attribute name="href">
<xsl:value-of select="umbraco.library:GetMedia(data[#alias='pdf'], 0)/data [#alias = 'umbracoFile']"/>
</xsl:attribute>
<strong>
<xsl:value-of select="#nodeName"/>
<span>
(<xsl:value-of select="$sizeAndSuffix"/>)
</span>
</strong>
<em>
<xsl:value-of select="data [#alias = 'PDFBeskrivelse']"/>
</em>
<img>
<xsl:attribute name="src">
<xsl:value-of select="data [#alias = 'PDFBillede']"/>
</xsl:attribute>
<xsl:attribute name="alt"></xsl:attribute>
<xsl:attribute name="height">200</xsl:attribute>
<xsl:attribute name="width">141</xsl:attribute>
</img>
</a>
</div>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
That should do the trick.

Resources