- 2 sequences of elements sorted increasing. , xsl outputs 1 sequence containing items , sorted them increasingly.
input:
<!doctype lists system "list.dtd"> <numbers> <list> <num val="2"/> <num val="5"/> <num val="8"/> <num val="12"/> <num val="20"/> <num val="32"/> </list> <list> <num val="4"/> <num val="7"/> <num val="10"/> <num val="29"/> <num val="30"/> </list> </numbers>
the output should be:
<?xml version="1.0" encoding="utf-8"?> <!doctype lists system "list.dtd"> <numbers> <list> <num val="2"/> <num val="4"/> <num val="5"/> <num val="7"/> <num val="8"/> <num val="10"/> <num val="12"/> <num val="20"/> <num val="29"/> <num val="30"/> <num val="32"/> </list> </numbers>
here xsl ,the result wrong ,could show me??
<xsl:transform 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 method="xml" version="1.0" encoding="utf-8" indent ="yes"/> <xsl:template match="/"> <xsl:apply-templates/> <xsl:text> </xsl:text> </xsl:template> <xsl:template match="lists"> <xsl:copy> <list> <xsl:call-template name="merge"> <xsl:with-param name ="num1" select="list[1]/item" as="element(item)*"/> <xsl:with-param name="num2" select ="list[2]/item" as="element(item)*"/> </xsl:call-template> </list> </xsl:copy> </xsl:template> <xsl:template name="merge" as="element(item)*"> <xsl:param name="num1" as="element(item)*"/> <xsl:param name="num2" as="element(item)*"/> <xsl:choose> <xsl:when test="empty($num1)"> <xsl:sequence select="$num2"/> </xsl:when> <xsl:when test="empty($num2)"> <xsl:sequence select="$num1"/> </xsl:when> <xsl:when test="$num2[1]/@val ge $num1[1]/@val"> <xsl:sequence select="$num1[1]"/> <xsl:call-template name="merge"> <xsl:with-param name="num1" select="$num1[position()>1]"/> <xsl:with-param name="num2" select="$num2[1]"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:sequence select="$num2[1]"/> <xsl:call-template name="merge"> <xsl:with-param name="num1" select="$num1[1]"/> <xsl:with-param name="num2" select="$num2[position()>1]"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:transform>
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0"> <xsl:output indent="yes"/> <xsl:template match="numbers"> <xsl:copy> <list> <!--process of num elements --> <xsl:apply-templates select="list/num"> <!--sort num elements @val, number ensure proper sort order--> <xsl:sort select="number(@val)"/> </xsl:apply-templates> </list> </xsl:copy> </xsl:template> <!--identity template - copies content forward default --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> </xsl:stylesheet>
if don't want use xsl:sort
, , want use stylesheet , custom "merge" template, there couple of adjustments need make in order work sample input. below corrected version inline comments explaining adjustments made:
<xsl:transform 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 method="xml" version="1.0" encoding="utf-8" indent ="yes"/> <xsl:template match="/"> <xsl:apply-templates/> <xsl:text> </xsl:text> </xsl:template> <!--issue#1: matching on "lists" --> <xsl:template match="numbers"> <xsl:copy> <list> <xsl:call-template name="merge"> <!--issue#2: these parameters restricted "item", not "num" --> <xsl:with-param name ="num1" select="list[1]/num" as="element(num)*"/> <xsl:with-param name="num2" select ="list[2]/num" as="element(num)*"/> </xsl:call-template> </list> </xsl:copy> </xsl:template> <!--issue#3: these output restricted "item", not "num" --> <xsl:template name="merge" as="element(num)*"> <!--issue#4: these parameters restricted "item", not "num" --> <xsl:param name="num1" as="element(num)*"/> <xsl:param name="num2" as="element(num)*"/> <xsl:choose> <xsl:when test="empty($num1)"> <xsl:sequence select="$num2"/> </xsl:when> <xsl:when test="empty($num2)"> <xsl:sequence select="$num1"/> </xsl:when> <!--issue#5: these values need evaluated numbers, string compare give bad results(e.g. "10" less "8") --> <xsl:when test="number($num2[1]/@val) ge number($num1[1]/@val)"> <xsl:sequence select="$num1[1]"/> <xsl:call-template name="merge"> <xsl:with-param name="num1" select="$num1[position()>1]"/> <xsl:with-param name="num2" select="$num2"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:sequence select="$num2[1]"/> <xsl:call-template name="merge"> <xsl:with-param name="num1" select="$num1"/> <xsl:with-param name="num2" select="$num2[position()>1]"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:transform>
Comments
Post a Comment