Search code examples
xsltxslt-1.0jdeveloper

How to populate a value based on an element in XSL 1.0


My source sample XML is as below

<QuoteData>
    <Components>
        <Component  ServiceOfferingId="XX"  StartDate="07/03/2016"  EndDate="12/31/9999"  SerialOrderNbr="xx"  StopReasonCode=""  IsBundle="N">
            <ServiceItem  ItemType="xx"  Type="2072"  ModelFeature="24E"  ProductId="2072 24E"  SerialOrderNbr="xx"  Quantity="1"  StartDate="07/03/2016"  EndDate="12/31/9999"  CustomerId="xx"  ServiceLevelId="xx"/>
        </Component>
        <Component  ServiceOfferingId="yy"  StartDate="07/03/2016"  EndDate="12/31/9999"  SerialOrderNbr="yy"  StopReasonCode=""  IsBundle="N">
            <ServiceItem  ItemType="yy"  Type="2072"  ModelFeature="24C"  ProductId="2072 24C"  SerialOrderNbr="yy"  Quantity="1"  StartDate="07/03/2016"  EndDate="12/31/9999"  CustomerId="yy"  ServiceLevelId="yy"/>
            <ServiceItem  ItemType="zz"  Type="2072"  ModelFeature="24E"  ProductId="2072 24E"  SerialOrderNbr="zz"  Quantity="1"  StartDate="07/03/2016"  EndDate="12/31/9999"  CustomerId="zz"  ServiceLevelId="zz"/>
        </Component>
    </Components>
    <Descriptions>
        <ProductDescription  Id="2072 24E"  Description="Customer EXPANSION"/>
        <ProductDescription  Id="2072 24C"  Description="Customer CONTROL"/>
    </Descriptions>
</QuoteData>

As per requirement each ServiceItem should be converted into a Line. So, in the above case, 3 lines shoule be created. In the Target, I should be able to populate Product Description based on the Product ID value. Currently I am unable to do that using XSL 1.0

Expected target XML should be like below:

<Payload>
    <Header></Header>
    <Line>
        <SerialOrderNbr>xx</SerialOrderNbr>
        <ModelFeature>24E</ModelFeature>
        <ProductId>2072 24E</ProductId>
        <ProductDescription>Customer EXPANSION</ProductDescription>
    </Line>  
    <Line>
        <SerialOrderNbr>xx</SerialOrderNbr>
        <ModelFeature>24C</ModelFeature>
        <ProductId>2072 24C</ProductId>
        <ProductDescription>Customer CONTROL</ProductDescription>
    </Line>
    <Line>
        <SerialOrderNbr>xx</SerialOrderNbr>
        <ModelFeature>24E</ModelFeature>
        <ProductId>2072 24E</ProductId>
        <ProductDescription>Customer EXPANSION</ProductDescription>
    </Line>
</Payload>

I tried using different functions to populate the target description, but I am either getting the first Description value in all the lines or no value at all is being populated. I am able to achieve the required functionality using a while loop and assign activity in Jdev 11g.

How can I do this in XSLT?


Solution

  • Using the following stylesheet is easily possible:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <xsl:output method="xml" /> 
      <xsl:template match="/QuoteData">
        <Payload>
          <xsl:for-each select="//ServiceItem">
            <line>
              <SerialOrderNbr><xsl:value-of select="@SerialOrderNbr" /></SerialOrderNbr>
              <ModelFeature><xsl:value-of select="@ModelFeature" /></ModelFeature>
              <ProductId><xsl:value-of select="@ProductId" /></ProductId>
              <ProductDescription><xsl:value-of select="//ProductDescription[@Id = current()/@ProductId]/@Description" /></ProductDescription>
            </line>
          </xsl:for-each>
        </Payload>
      </xsl:template>    
    </xsl:stylesheet>
    

    Its output is:

    <?xml version="1.0"?>
    <Payload>
        <line>
            <SerialOrderNbr>xx</SerialOrderNbr>
            <ModelFeature>24E</ModelFeature>
            <ProductId>2072 24E</ProductId>
            <ProductDescription>Customer EXPANSION</ProductDescription>
        </line>
        <line>
            <SerialOrderNbr>yy</SerialOrderNbr>
            <ModelFeature>24C</ModelFeature>
            <ProductId>2072 24C</ProductId>
            <ProductDescription>Customer CONTROL</ProductDescription>
        </line>
        <line>
            <SerialOrderNbr>zz</SerialOrderNbr>
            <ModelFeature>24E</ModelFeature>
            <ProductId>2072 24E</ProductId>
            <ProductDescription>Customer EXPANSION</ProductDescription>
        </line>
    </Payload>
    

    This is not exactly what you claimed to expect as output, because your version of the desired output seems to be erroneous. In your output version all SerialOrderNbrs have 'xx' as value, but in your source XML they are different.