0

I have below sample xml data. The scenario is that productNo element has to be concatenated with type element value and number element value when the type=#. the concatenated output has to be concatenated with each serialNumber element in that orderItem record.

the final requirement is: 1. when type element is '#' then productNo concatenation with each type element and number elements should be concatenated with each serialNumber element in each orderItem record. 2. when type element doesn't have '#' then productNo should be concatenated with each serialNumber element in each orderItem record

          <orderItems>
              <orderItem itemNo="0100" sapItemNo="10">
                 <productNo>WK302EA</productNo>
                 <itemShipDetails>
                    <itemShipDetail>
                       <serialNumber>CZC132BM61</serialNumber>
                    </itemShipDetail>
                    <itemShipDetail>
                       <serialNumber>CZC1331JR2</serialNumber>
                    </itemShipDetail>
                    <itemShipDetail>
                       <serialNumber>CZC1331JR3</serialNumber>
                    </itemShipDetail>
                 </itemShipDetails>
                 <options>
                    <option ln="01" type="" sapItemNo="10">
                       <number>WK302EA</number>
                    </option>
                    <option ln="02" type="#" sapItemNo="10">
                       <number>ABN</number>
                    </option>
                    <option ln="03" type="#" sapItemNo="10">
                       <number>ASZ</number>
                    </option>
                 </options>
              </orderItem>
              <orderItem itemNo="0200" sapItemNo="20">
                 <productNo>VY623AA</productNo>
                 <itemShipDetails>
                    <itemShipDetail>
                       <serialNumber>CN3129300D</serialNumber>
                    </itemShipDetail>
                    <itemShipDetail>
                       <serialNumber>CN3129300Z</serialNumber>
                    </itemShipDetail>
                    <itemShipDetail>
                       <serialNumber>CN3129306S</serialNumber>
                    </itemShipDetail>
                    <itemShipDetail>
                       <serialNumber>CN312930LM</serialNumber>
                    </itemShipDetail>
                 </itemShipDetails>
                 <options>
                    <option ln="04" type="" sapItemNo="20">
                       <number>VY623AA</number>
                    </option>
                    <option ln="05" type="#" sapItemNo="20">
                       <number>ABN</number>
                    </option>
                 </options>
              </orderItem>
              <orderItem itemNo="0300" sapItemNo="30">
                 <productNo>VY623AS</productNo>
                 <itemShipDetails>
                    <itemShipDetail>
                       <serialNumber>CN3129300X</serialNumber>
                    </itemShipDetail>
                    <itemShipDetail>
                       <serialNumber>CN3129300P</serialNumber>
                    </itemShipDetail>
                 </itemShipDetails>
                 <options>
                    <option ln="06" type="" sapItemNo="30">
                       <number>VY623AS</number>
                    </option>
        <option ln="07" type="M" sapItemNo="30">
                       <number>ABC</number>
                    </option>
                 </options>
              </orderItem>
            </orderItems>

The expected Output is:

    <orders>
    <serialNO>WK302EA#ABN|CZC132BM61</serialNO>
    <serialNO>WK302EA#ABN|CZC1331JR2</serialNO>
    <serialNO>WK302EA#ABN|CZC1331JR3</serialNO>
    <serialNO>WK302EA#ASZ|CZC132BM61</serialNO>
    <serialNO>WK302EA#ASZ|CZC1331JR2</serialNO>
    <serialNO>WK302EA#ASZ|CZC1331JR3</serialNO>

    <serialNO>VY623AA#ABN|CN3129300D</serialNO>
    <serialNO>VY623AA#ABN|CN3129300Z</serialNO>
    <serialNO>VY623AA#ABN|CN3129306S</serialNO>
    <serialNO>VY623AA#ABN|CN312930LM</serialNO>

    <serialNO>VY623AS|CN3129300X</serialNO>
    <serialNO>VY623AS|CN3129300P</serialNO>
    </orders>
user1658369
  • 99
  • 1
  • 11

3 Answers3

1

Some easy templates with proper selects should do it. A template can have parameters just like function.

(tested the code, so it should produce the correct output)

<xsl:template match="orderItems">
    <orders>
        <xsl:apply-templates select="orderItem/options/option[@type != '']"/>
    </orders>
</xsl:template>

<xsl:template match="option[@type = '#']">
    <xsl:apply-templates select="../../itemShipDetails/itemShipDetail/serialNumber">
        <xsl:with-param name="productNo" select="concat(../../productNo, '#', number)"/>
    </xsl:apply-templates>
</xsl:template>

<xsl:template match="option[@type != '#']">
    <xsl:apply-templates select="../../itemShipDetails/itemShipDetail/serialNumber">
        <xsl:with-param name="productNo" select="../../productNo"/>
    </xsl:apply-templates>
</xsl:template>

<xsl:template match="serialNumber">
    <xsl:param name="productNo"/>
    <serialNO><xsl:value-of select="concat($productNo, '|', .)"/></serialNO>
</xsl:template>
Joep
  • 4,003
  • 3
  • 28
  • 32
  • This is what I get: `CZC132BM61CZC1331JR2CZC1331JR3CZC132BM61CZC1331JR2CZC1331JR3CN3129300DCN3129300ZCN3129306SCN312930LMCN3129300XCN3129300P` — please validate your code – mousio Dec 09 '12 at 14:49
  • Fixed the small typo in last template from searialNumber -> serialNumber. – Joep Dec 09 '12 at 22:01
0

Let me write that for you in pseudo codes.

You need one output line
 For each orderItem
  if there is at least one option where type = #
   For each options/option where type = #
    For each itemShipDetail
     One output element Serial No productNo + # + this-option/number + | + this-itemShipDetail/Number
  else
   For each ItemShipDetail
    One output element Serial No productNo + # + this-itemShipDetail/Number

Populate that with some (.)s and (..)s to get your final output.

yem yem yen
  • 309
  • 2
  • 10
0

If that is the order in which the serialNO items are required, then this transform:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

<xsl:template match="orderItems">
  <orders>
    <xsl:apply-templates select="orderItem/productNo"/>
  </orders>
</xsl:template>

<!-- option(s) type '#' present: work with those as base -->
<xsl:template match="productNo[following-sibling::options/option/@type='#']">
  <xsl:apply-templates select="following-sibling::options/option[@type='#']"/>
</xsl:template>

<!-- no options type '#' present: just process its serial numbers
     (passing the product number) -->
<xsl:template match="productNo">
  <xsl:apply-templates select="following-sibling::itemShipDetails/itemShipDetail/serialNumber">
    <xsl:with-param name="productNoAndOptionNo"
      select="."/>
  </xsl:apply-templates>
</xsl:template>

<!-- option type '#': now process the serial numbers
     (passing the product number and option number concatenation -->
<xsl:template match="option[@type='#']">
  <xsl:apply-templates select="../preceding-sibling::itemShipDetails/itemShipDetail/serialNumber">
    <xsl:with-param name="productNoAndOptionNo"
      select="concat(../preceding-sibling::productNo, '#', number)"/>
  </xsl:apply-templates>
</xsl:template>

<!-- output formatted serial number -->
<xsl:template match="serialNumber">
  <xsl:param name="productNoAndOptionNo"/>
  <serialNO>
    <xsl:value-of select="concat($productNoAndOptionNo, '|', .)"/>
  </serialNO>
</xsl:template> 

</xsl:stylesheet>

when applied to your document, produces the following result:

<orders>
<serialNO>WK302EA#ABN|CZC132BM61</serialNO>
<serialNO>WK302EA#ABN|CZC1331JR2</serialNO>
<serialNO>WK302EA#ABN|CZC1331JR3</serialNO>
<serialNO>WK302EA#ASZ|CZC132BM61</serialNO>
<serialNO>WK302EA#ASZ|CZC1331JR2</serialNO>
<serialNO>WK302EA#ASZ|CZC1331JR3</serialNO>
<serialNO>VY623AA#ABN|CN3129300D</serialNO>
<serialNO>VY623AA#ABN|CN3129300Z</serialNO>
<serialNO>VY623AA#ABN|CN3129306S</serialNO>
<serialNO>VY623AA#ABN|CN312930LM</serialNO>
<serialNO>VY623AS|CN3129300X</serialNO>
<serialNO>VY623AS|CN3129300P</serialNO>
</orders>
mousio
  • 10,079
  • 4
  • 34
  • 43