XSLT problem

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • AndreasAndersson
    New Member
    • Nov 2007
    • 1

    XSLT problem

    Hi!

    I'm trying to design an XSLT in order to transform an XML document into another XML document.

    The source XML looks something like this:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <Orders>
    <Order>
    <OrderHeader>
    <sCustomerNo>116442</sCustomerNo>
    <sOrderNo>8245673</sOrderNo>
    </OrderHeader>
    <OrderRows>
    <OrderRow>
    <sOrderLineNo>1</sOrderLineNo>
    <sArticleNo>102448</sArticleNo>
    <iQuantity>3</iQuantity>
    </OrderRow>
    <OrderRow>
    <sOrderLineNo>2</sOrderLineNo>
    <sArticleNo>102448</sArticleNo>
    <iQuantity>4</iQuantity>
    </OrderRow>
    </OrderRows>
    </Order>
    <Order>
    <OrderHeader>
    <sCustomerNo>116448</sCustomerNo>
    <sOrderNo>8245677</sOrderNo>
    </OrderHeader>
    <OrderRows>
    <OrderRow>
    <sOrderLineNo>1</sOrderLineNo>
    <sArticleNo>102448</sArticleNo>
    <iQuantity>7</iQuantity>
    </OrderRow>
    </OrderRows>
    </Order>
    </Orders>
    And I want the transformed XML to look like this:

    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <Orders>
    <Order>
    <OrderNumber>8245673</OrderNumber>
    <Customer>116442</Customer>
    <OrderLine>
    <ArticleNumber>102448</ArticleNumber>
    <Quantity>7</Quantity>
    </OrderLine>
    </Order>
    <Order>
    <OrderNumber>8245677</OrderNumber>
    <Customer>116448</Customer>
    <OrderLine>
    <ArticleNumber>102448</ArticleNumber>
    <Quantity>7</Quantity>
    </OrderLine>
    </Order>
    </Orders>
    The challenge is to group all orderlines with the same article number and summarizing their quantities.

    In order to acheive this I´ve found something called the Muenchian method: http://www.jenitennison.com/xslt/gro...muenchian.html

    Code:
    <xsl:key name="orderrows-by-articleno" match="OrderRows/OrderRow" use="sArticleNo" />
    ...
    <xsl:for-each select="OrderRows/OrderRow[count(. | key(''''orderrows-by-articleno'''', sArticleNo)[1]) = 1]">
    <xsl:variable name="sArticleNo">
    <xsl:value-of select="sArticleNo"/>
    </xsl:variable>
    <OrderLine>
    <ArticleNumber><xsl:value-of select="sArticleNo" /></ArticleNumber>
    <Quantity><xsl:value-of select="sum(../../OrderRows/OrderRow[sArticleNo = $sArticleNo]/iQuantity)"/></Quantity>
    </OrderLine>
    </xsl:for-each>
    But since the "orderrows-by-articleno"-key matches for all OrderRows/OrderRow in the entiry document and not per Order, I get this result:

    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <Orders>
    <Order>
    <OrderNumber>8245673</OrderNumber>
    <Customer>116442</Customer>
    <OrderLine>
    <ArticleNumber>102448</ArticleNumber>
    <Quantity>7</Quantity>
    </OrderLine>
    </Order>
    <Order>
    <OrderNumber>8245677</OrderNumber>
    <Customer>116448</Customer>
    </Order>
    </Orders>
    Anyone got any idea how to make this grouping per order?
  • jkmyoung
    Recognized Expert Top Contributor
    • Mar 2006
    • 2057

    #2
    [code=xml]<xsl:key name="orderrows-by-articleno" match="OrderRow s/OrderRow" use="concat(sAr ticleNo,generat e-id(..))" />[/code]

    Note this should really be generate-id(../..) to group on Order as well, but I've cheated a little and assumed that OrderRows only appear once per Order.

    For-each becomes
    [code=xml]<xsl:for-each select="OrderRo ws/OrderRow[count(. | key('orderrows-by-articleno', concat(sArticle No,generate-id(..)))[1]) = 1]">[/code]

    Also, why not use the key in summing? You've already created it.

    [code=xml]<xsl:value-of select="sum(key ('orderrows-by-articleno', concat(sArticle No,generate-id(..)))/iQuantity)"/>[/code]

    Comment

    Working...