-1

i need to relate Parent/sscc with its Logistic/sscc.we need to check same Parent/sscc in the input file & need to relate that with its logistic/sscc.As a result output must be logistic/sscc with its parent/sscc. i provided input and output details. New code not copying the Parent/sscc with its logistic /sscc

Input:

<?xml version="1.0" encoding="UTF-8"?>
<wONM>
   <Standard>
      <Sender>1</Sender>                
   </Standard>
   <warehousingNotification>      
      <warehousingIdentification>
         <entityIdentification>000031115</entityIdentification>
      </warehousingIdentification>
      <warehousingOperationsTransaction>
        <SNumber>1</SNumber>
         <warehousingOperationsLocation>
            <inventoryLocation>        
            </inventoryLocation>
            <logistic>
               <sscc>101</sscc>
               <parent>
                  <sscc>203</sscc>
               </parent>               
            </logistic>
            <logistic>
               <sscc>190</sscc>
               <parent>
                  <sscc>204</sscc>
               </parent>              
            </logistic>
            <logistic>
               <sscc>102</sscc>
               <parent>
                  <sscc>203</sscc>
               </parent>               
            </logistic>
            <logistic>
               <sscc>191</sscc>
               <parent>
                  <sscc>204</sscc>
               </parent>               
            </logistic>
         </warehousingOperationsLocation>
      </warehousingOperationsTransaction>
      <warehousingOperationsTransaction>
        <SNumber>2</SNumber>
         <warehousingOperationsLocation>
            <inventoryLocation>
            </inventoryLocation>
            <logistic>
               <sscc>192</sscc>
               <parent>
                  <sscc>204</sscc>
               </parent>               
            </logistic>
            <logistic>
               <sscc>107</sscc>
               <parent>
                  <sscc>203</sscc>
               </parent>               
            </logistic>
            <logistic>
               <sscc>197</sscc>
               <parent>
                  <sscc>204</sscc>
               </parent>               
            </logistic>
            <logistic>
               <sscc>108</sscc>
               <parent>
                  <sscc>203</sscc>
               </parent>               
            </logistic>
         </warehousingOperationsLocation>
      </warehousingOperationsTransaction>
      <warehousingOperationsTransaction>
         <SNumber>3</SNumber>
         <warehousingOperationsLocation>
            <inventoryLocation>
            </inventoryLocation>
            <logistic>
               <sscc>101</sscc>
               <parent>
                  <sscc>205</sscc>
               </parent>              
            </logistic>
            <logistic>
               <sscc>102</sscc>
               <parent>
                  <sscc>206</sscc>
               </parent>               
            </logistic>
            <logistic>
               <sscc>109</sscc>
               <parent>
                  <sscc>203</sscc>
               </parent>              
            </logistic>
            <logistic>
               <sscc>110</sscc>
               <parent>
                  <sscc>203</sscc>
               </parent>               
            </logistic>
         </warehousingOperationsLocation>
      </warehousingOperationsTransaction>
   </warehousingNotification>
</wONM>

Output:

<?xml version="1.0" encoding="UTF-8"?>
<wONM>
   <Standard>
      <Sender>1</Sender>                
   </Standard>
   <warehousingNotification>      
       <warehousingIdentification>
         <entityIdentification>000031115</entityIdentification>
      </warehousingIdentification>
      <warehousingOperationsTransaction>
        <SNumber>1</SNumber>
         <warehousingOperationsLocation>
            <inventoryLocation>        
            </inventoryLocation>
            <logistic>
               <sscc>101</sscc>
               <sscc>102</sscc>
               <sscc>107</sscc>
               <sscc>108</sscc>
               <sscc>109</sscc>
               <sscc>110</sscc>
               <parent>
                  <sscc>203</sscc>
               </parent>               
            </logistic>
            <logistic>
               <sscc>190</sscc>
               <sscc>191</sscc>
               <sscc>192</sscc>
               <sscc>197</sscc>
               <parent>
                  <sscc>204</sscc>
               </parent>              
            </logistic>
            <logistic>
               <sscc>101</sscc>
               <parent>
                  <sscc>205</sscc>
               </parent>               
            </logistic>
            <logistic>
               <sscc>102</sscc>
               <parent>
                  <sscc>206</sscc>
               </parent>               
            </logistic>
         </warehousingOperationsLocation>
      </warehousingOperationsTransaction>   

   </warehousingNotification>
</wONM>

Sree
  • 17
  • 7

3 Answers3

1

Like mentioned in the comments, you haven't shown any attempt at solving this yourself.

Instead of giving you the stylesheet (which I've already written), I'll break down the steps I followed and hopefully you can attempt it yourself. If you update the question with an attempt that shows effort, I will add my full stylesheet to my answer.

STEP 1

Start with an identity transform. This will basically output whatever is input unchanged.

I won't go into the details of what could be different between input and output.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!--step 1-->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

STEP 2

The first change (in document order) I see in your output is that you are combining all warehousingOperationsTransaction elements into a single element.

To do this, we can add a template that matches the parent (warehousingNotification).

(Again, I start with xsl:copy/xsl:apply-templates to get the same output unchanged; just like the identity transform.)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!--step 1-->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!--step 2-->    
  <xsl:template match="warehousingNotification">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

STEP 3

Now we can change the xsl:apply-templates to not process the existing warehousingOperationsTransaction element.

We can also create the new warehousingOperationsTransaction along with the other static elements (SNumber, warehousingOperationsLocation, and inventoryLocation).

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="parent" match="parent/sscc" use="."/>
  <xsl:key name="sscc_by_parent" match="sscc" use="../parent/sscc"/>

  <!--step 1-->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>


  <!--step 2-->
  <xsl:template match="warehousingNotification">
    <xsl:copy>
      <!--step 3 (exclude warehousingOperationsTransaction and add a new one)-->
      <xsl:apply-templates select="@*|node()[not(self::warehousingOperationsTransaction)]"/>
      <warehousingOperationsTransaction>
        <SNumber>1</SNumber>
        <warehousingOperationsLocation>
          <inventoryLocation/>          
        </warehousingOperationsLocation>
      </warehousingOperationsTransaction>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

- TIMEOUT -

For the next steps I'm only providing comments in the XSLT where I would put the code for each step. This is where you take over and come back with specific questions if you need help. (Except for the xsl:key's; I'll give you those.)

You will need to learn about Muenchian Grouping for the next steps. One good reference can be found here: Jeni's XSLT Pages: Grouping Using the Muenchian Method

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!--step 4-->

  <!--step 1-->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>


  <!--step 2-->
  <xsl:template match="warehousingNotification">
    <xsl:copy>
      <!--step 3 (exclude warehousingOperationsTransaction and add a new one)-->
      <xsl:apply-templates select="@*|node()[not(self::warehousingOperationsTransaction)]"/>
      <warehousingOperationsTransaction>
        <SNumber>1</SNumber>
        <warehousingOperationsLocation>
          <inventoryLocation/>
          <!--step 5 (create logistic for each parent)-->
              <!--step 6 (output the sscc's based on parent (current context))-->
        </warehousingOperationsLocation>
      </warehousingOperationsTransaction>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

STEP 4

You need to create the xsl:key elements for grouping.

Since you're creating a new logic element for every unique parent/sscc, create a key for the parents.

You also need a key for all the logistic/sscc elements based on the sibling parent/sscc.

To help get you started, these are the keys I used:

<xsl:key name="parent" match="parent/sscc" use="."/>
<xsl:key name="sscc_by_parent" match="logistic/sscc" use="../parent/sscc"/>

STEP 5

Create a logistic/parent element for each (xsl:for-each) unique parent.

The key to this (no pun intended) is to look at Jenny's example that mentions "There are a couple of generic methods of testing whether two nodes are identical".

Hint: you'll be using the key() function in a predicate. You'll want to use the "parent" key.

STEP 6

Now we need to insert all of the sscc elements in the logistic element.

To do this you can use an xsl:copy-of placed right before the new parent element. You'll use the key() function again to access the sscc_by_parent key.

The only tricky part of this is what to use for the second argument to key(). Since you probably used an xsl:for-each in step 5 to select .//parent/sscc, the value we need is already the current context. (The link is the hint.)

Good luck!

This should be enough to at least get you started. If not, please consider formal training or hiring a consultant.

EDIT: Moving to XSLT 2.0 was the right decision. Here's the 1.0 stylesheet; maybe it will help someone else in the future.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!--step 4-->
  <xsl:key name="parent" match="parent/sscc" use="."/>
  <xsl:key name="sscc_by_parent" match="logistic/sscc" use="../parent/sscc"/>

  <!--step 1-->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>


  <!--step 2-->
  <xsl:template match="warehousingNotification">
    <xsl:copy>
      <!--step 3 (exclude warehousingOperationsTransaction and add a new one)-->
      <xsl:apply-templates select="@*|node()[not(self::warehousingOperationsTransaction)]"/>
      <warehousingOperationsTransaction>
        <SNumber>1</SNumber>
        <warehousingOperationsLocation>
          <inventoryLocation/>
          <!--step 5 (create logistic for each parent)-->
          <xsl:for-each select=".//parent/sscc[count(.|key('parent', .)[1]) = 1]">
            <logistic>
              <!--step 6 (output the sscc's based on parent (current context))-->
              <xsl:copy-of select="key('sscc_by_parent', current())"/>
              <parent>
                <xsl:copy-of select="."/>
              </parent>
            </logistic>
          </xsl:for-each>
        </warehousingOperationsLocation>
      </warehousingOperationsTransaction>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Fiddle: http://xsltfiddle.liberty-development.net/3MvmXiZ

Daniel Haley
  • 51,389
  • 6
  • 69
  • 95
0

This looks like a standard grouping problem. In XSLT 2.0+ it's <xsl:for-each-group select=".//logistic" group-by="parent/sscc">. Grouping in XSLT 1.0 is a lot more difficult, but if you really can't move forward to an XSLT 2.0 processor, then read up on Muenchian grouping techniques, which are covered in every XSLT 1.0 textbook and many online tutorials.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • unfortunately our setup is XSLT 1.0 only. – Sree May 12 '20 at 12:16
  • 1
    XSLT 1.0 is becoming very old -- it's really time you considered moving to newer technology. It's going to become increasingly difficult to find people prepared to help with XSLT 1.0 problems that would be easily solved if you upgraded. – Michael Kay May 12 '20 at 17:04
  • Yeah, i checked but as of now i need to use 1.0 only – Sree May 13 '20 at 11:13
  • @Sree - please see my answer. It includes a useful link to a Muenchian grouping resource. – Daniel Haley May 14 '20 at 18:07
-1

This can be achieved using XSLT 2.0 grouping, below is the complete XSLT code to achieve the desired output:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">

    <xsl:output indent="yes"></xsl:output>

    <xsl:template match="node()|@*">
        <xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>
    </xsl:template>

    <xsl:template match="*:wONM">
        <wONM>
            <xsl:apply-templates select="*:Standard"></xsl:apply-templates>
            <warehousingNotification>
                <xsl:apply-templates select="*:warehousingNotification/*:warehousingIdentification"/>
                <warehousingOperationsTransaction>
                    <xsl:apply-templates select="*:warehousingNotification/*:warehousingOperationsTransaction/*:SNumber"/>
                    <warehousingOperationsLocation>
                        <xsl:apply-templates select="*:warehousingNotification/*:warehousingOperationsTransaction/*:warehousingOperationsLocation/*:inventoryLocation"></xsl:apply-templates>
                        <xsl:for-each-group select="*:warehousingNotification//*:logistic" group-by="*:parent/*:sscc">
                            <logisticaaa>
                                <xsl:for-each select="current-group()">
                                    <sscc>
                                        <xsl:value-of select="./*:sscc"/>
                                    </sscc>
                                </xsl:for-each> 
                                <parent>
                                    <sscc><xsl:value-of select="current-grouping-key()"/></sscc>
                                </parent>
                            </logisticaaa>
                        </xsl:for-each-group>
                    </warehousingOperationsLocation>
                </warehousingOperationsTransaction>
            </warehousingNotification>            
        </wONM>
    </xsl:template>

</xsl:stylesheet>