none
bts2006 r2 loop question (parent/child) RRS feed

  • Question

  • I need a resultxml that loops over a childrecord and if there is no childrecord there over the parentrecord/

    Can this be done using the mapper or do i need to use XSLT?

    Sourcesample

    <BOMLine>
    	<BOMQty>48.0000</BOMQty>
    	<ItemId>Item1</ItemId>
    	<BOMReference>
    	    <Qty>23.0000</Qty>
    	    <Reference>Ref1</Reference>
    	</BOMReference>
    	<BOMReference>
    	    <Qty>25.0000</Qty>
    	    <Reference>ref2</Reference>
    	</BOMReference>
    </BOMLine>
    <BOMLine>
    	<BOMQty>48.0000</BOMQty>
    	<ItemId>Item2</ItemId>
    </BOMLine>
    <BOMLine>
    	<BOMQty>24.0000</BOMQty>
    	<ItemId>Item3</ItemId>
    	<BOMReference>
      	    <Qty>24.0000</Qty>
    	    <Reference>ref3</Reference>
    	</BOMReference>
    </BOMLine>
    Desired result
    <ResultBOM>
    	<Qty>23</Qty>
            <ItemId>Item1</ItemId>
    	<Reference>Ref1</Reference>
    </ResultBOM>
    <ResultBOM>
    	<Qty>25</Qty>
            <ItemId>Item1</ItemId>
    	<Reference>Ref2</Reference>
    </ResultBOM>
    <ResultBOM>
    	<Qty>48</Qty>
            <ItemId>Item2</ItemId>
    	<Reference></Reference>
    </ResultBOM>
    <ResultBOM>
    	<Qty>24</Qty>
            <ItemId>Item3</ItemId>
    	<Reference>Ref3</Reference>
    </ResultBOM>


    Kind regards Isabelledc

    Monday, October 20, 2014 8:21 AM

Answers

  • For clarity, it is not always best to use custom XSLT.

    Actually what you want is relatively straight forward as, based on the output sample output, there doesn't need to be two loops.

    The easiest way:

    1. Link BOMQty and Qty through to a Scripting Functoid.
    2. In there, test Qty for length.
    3. If Qty.Length >0, return Qty, else return BOMQty.

    Qty is just an optional nephew node to BOMQty, not another loop.

    Monday, October 20, 2014 11:17 AM
    Moderator

All replies

  • It would be easier if you use custom XSLT :)

    Regards &lt;br/&gt; When you see answers and helpful posts,&lt;br/&gt; please click Vote As Helpful, Propose As Answer, and/or Mark As Answer

    Monday, October 20, 2014 9:45 AM
    Answerer
  • Hi,

    It is alwasy best to use XSLT. You can try the below xslt. Hope this helps to get ur output

    Copy in scripting function and assign it to the destination record "ResultBOM".

    <xsl:template name="Sample">
     <xsl:for-each select ="xpath of BOMLine"> <!--Provide complete xpath of BOMLine record-->
     <xsl:choose>
     <xsl:when test="BOMReference">
     <xsl:element name ="ResultBOM">
     <xsl:element name = "Qty">
     <xsl:value-of select="BOMReference/Qty/text()"/>
     </element>
     <xsl:element name = "ItemId">
     <xsl:value-of select="ItemId/text()"/>
     </element>
     <xsl:element name = "Reference">
     <xsl:value-of select="BOMReference/Reference/text()"/>
     </element>
     </xsl:when>
     <xsl:otherwise>
     <xsl:element name ="ResultBOM">
     <xsl:element name = "Qty">
     <xsl:value-of select="BOMQty/text()"/>
     </element>
     <xsl:element name = "ItemId">
     <xsl:value-of select="ItemId/text()"/>
     </element>
     <xsl:element name = "Reference">
     <xsl:value-of select="BOMReference/Reference/text()"/>
     </element>
     </xsl:otherwise>
     </xsl:choose>
     </xsl:for-each>
     </xsl:template>

    Thanks


    • Edited by Ismailmgl Monday, October 20, 2014 10:22 AM
    Monday, October 20, 2014 10:13 AM
  • For clarity, it is not always best to use custom XSLT.

    Actually what you want is relatively straight forward as, based on the output sample output, there doesn't need to be two loops.

    The easiest way:

    1. Link BOMQty and Qty through to a Scripting Functoid.
    2. In there, test Qty for length.
    3. If Qty.Length >0, return Qty, else return BOMQty.

    Qty is just an optional nephew node to BOMQty, not another loop.

    Monday, October 20, 2014 11:17 AM
    Moderator
  • If you prefer xslt, I tested below for you and works as you needs:

    <Root>
    	<xsl:for-each select="/Root/BOMLine">
    		<xsl:variable name="var:itemID" select="ItemId/text()" />
    		<xsl:if test="not(BOMReference)">
    			<ResultBOM>
    				<xsl:variable name="var:qty" select="BOMQty/text()" />
    				<Qty>
    					<xsl:value-of select="$var:qty" />
    				</Qty>
    				<ItemId>
    					<xsl:value-of select="$var:itemID" />
    				</ItemId>
    				<Reference/>
    			</ResultBOM>
    		</xsl:if>
    		<xsl:if test="BOMReference">
    			<xsl:for-each select="BOMReference">
    				<ResultBOM>
    					<Qty>
    						<xsl:value-of select="Qty/text()" />
    					</Qty>
    					<ItemId>
    						<xsl:value-of select="$var:itemID" />
    					</ItemId>
    					<Reference>
    						<xsl:value-of select="Reference" />
    					</Reference>
    				</ResultBOM>
    			</xsl:for-each>
    		</xsl:if>
    	</xsl:for-each>
    </Root>		

    FYI: I assumed "Root" because your XML above doesn't have a root.


    Please mark it as Answer if this answers your question
    Thanks.
    Mo
    The contents I write here is my personal views, not the view of my employer and anyone else.



    • Edited by Mohan Raj Aryal Tuesday, October 21, 2014 2:56 AM Correction: Map approach execluded one record
    Tuesday, October 21, 2014 2:53 AM