locked
Mapping Using XSLT RRS feed

  • Question

  • My Source message looks like

    <Orders>

    <Order>

    <OrderNumber>1</OrderNumber>

    <ItemNumber>1</ItemNumber>

    <ItemPrice>9.0</ItemPrice>

    </Order>

    <Order>

    <OrderNumber>1</OrderNumber>

    <ItemNumber>2</ItemNumber>

    <ItemPrice>9.0</ItemPrice>

    </Order>

    <Order>....</Order> //With Different Order Numbers

    </Order>

    And Target message should look like

    <CanonicalOrders>

    <Order>

    <Item>

    <OrderNumber>1</OrderNumber>

    <ItemNumber>1</ItemNumber>

    <ItemPrice>9.0</ItemPrice>

    </Item>

    <Item>

    <OrderNumber>1</OrderNumber>

    <ItemNumber>2</ItemNumber>

    <ItemPrice>9.0</ItemPrice>

    </Item>

    </Order>

    <Order>

    ..... //Other Orders

    </Order>

    </CanonicalOrders>

    I thought of using XSLT then I realised that I can't reassign variables in there so can't figure out of new record is not from existing orderId.

    What should I do for this?

    Any advise please.


    Tuesday, February 9, 2016 12:30 PM

Answers

  • No, you can do it in XSLT, just that preceding-sibling is not the right pattern.

    Grouping by key value (as linked above) is what you want to do.

    • Proposed as answer by Angie Xu Tuesday, February 23, 2016 12:59 AM
    • Marked as answer by Angie Xu Tuesday, February 23, 2016 12:59 AM
    Tuesday, February 9, 2016 4:10 PM
    Moderator

All replies

  • I think you can handle this without using custom xslt as well, but in case you do want / need XSLT, you should look at the preceding-sibling sibling xslt method.
    Using this you can check if the ordernumber is different from the preceding order number.

    Tuesday, February 9, 2016 12:38 PM
  • So, what exact problem are you having?  The source and destination don't look all that different.

    I can see what might be the issue, the unusual grouping of the Items.

    Have you contacted the source of this Xml to see if they can provide you with a better, more standard format?  Don't be afraid to point out that what they are producing is making it harder to work with than it needs to be.  (Yes, I'm saying they are causing, perhaps unknowingly, a problem for you.)

    If they cannot change it, the next thing you should do is inform you management that, because of their output, you have to spend extra time 'fixing' it before using it in you app.

    Finally, the prevailing way to address this is with the Meunchien Method in xslt to first, re-group the records before again mapping to the final format.

    Grouping in xslt:

    http://www.jenitennison.com/xslt/grouping/muenchian.html

    https://en.wikipedia.org/wiki/XSLT/Muenchian_grouping

    Tuesday, February 9, 2016 12:55 PM
    Moderator
  • Thanks Eldert,

    Let me look at "preceding-sibling" method. I guess this is what I wanted. Would you please also let me know how can I do this without using XSLT?

    Regards,


    Tuesday, February 9, 2016 12:56 PM
  • Please take a look at the inline XSLT I am applying and it's giving me XSLT compilation error. Compilation error is for the lines where I am trying to initialise old-order-number and old-line-number.
    <ns0:CanonicalOrders xmlns:ns0="http://Something.Schemas.CanonicalOrders">
                
          <xsl:for-each select="/*[local-name()='Orders' and namespace-uri()='http://Something.Schemas.Public']/*[local-name()='Order' and namespace-uri()='']">
          <xsl:variable name="new-order-number"  select="current()/*[local-name()='Order' and namespace-uri()='']"/>
          <xsl:variable name="new-line-number"  select="current()/*[local-name()='Line' and namespace-uri()='']" />
          <xsl:variable name="old-order-number" select="preceding-sibling::/*[local-name()='Orders' and namespace-uri()='http://Something.Schemas.Public']/*[local-name()='Order' and namespace-uri()='']/*[local-name()='Order' and namespace-uri()='']"/>
          <xsl:variable name="old-line-number"  select="preceding-sibling::/*[local-name()='Orders' and namespace-uri()='http://Something.Schemas.Public']/*[local-name()='Order' and namespace-uri()='']/*[local-name()='Line' and namespace-uri()='']"/>
          
          <xsl:choose>
            
            <xsl:when test="$new-order-number = $old-order-number">
              <Item>
                <Order>
                  <xsl:value-of select="$old-order-number"/>
                </Order>
                <Line>
                  <xsl:value-of select="$old-line-number"/>
                </Line>
              </Item>
            </xsl:when>
            
            <xsl:otherwise>
              
                        
              <Order>
                <Items>
              <xsl:choose>
                
                <xsl:when test="$new-line-number = $old-line-number">
                </xsl:when>
                
                <xsl:otherwise>
                  <Item>
                    <Order>
                      <xsl:value-of select="$old-order-number"/>
                    </Order>
                    <Line>
                      <xsl:value-of select="$old-line-number"/>
                    </Line>
                  </Item>  
                </xsl:otherwise>
                
              </xsl:choose>
                </Items>
              </Order>
            </xsl:otherwise>
          </xsl:choose>
    
        </xsl:for-each>
    </ns0:CanonicalOrders>
    Please advise.
    Tuesday, February 9, 2016 1:32 PM
  • Thanks Johns,

    I point this out already but making a change from the supplier side is going to be very costly so we have to handle it at our end. :(

    I will look at the links you posted.

    regards,

    Tuesday, February 9, 2016 1:34 PM
  • I was able to fix XSLT compilation issue. As XPath after preceding-sibling should be Order/Order and Order/Line.

    But I am not able to get desired output using Xslt.  :(

    Seems like I have to use C# for this mapping.

    Tuesday, February 9, 2016 3:28 PM
  • No, you can do it in XSLT, just that preceding-sibling is not the right pattern.

    Grouping by key value (as linked above) is what you want to do.

    • Proposed as answer by Angie Xu Tuesday, February 23, 2016 12:59 AM
    • Marked as answer by Angie Xu Tuesday, February 23, 2016 12:59 AM
    Tuesday, February 9, 2016 4:10 PM
    Moderator