XSLT combine multiple Parents

I’m new to XSLT. I’m trying to create an XSLT

Here’s the XML Code

<?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet href="orders.xslt" type="text/xsl"?> <report>   <orders>     <order>       <order_id>123</order_id>       <order_name>Doritos</order_name>     </order>     <order>       <order_id>234</order_id>       <order_name>Pringles</order_name>     </order>   </orders>   <order_actions>     <order_action>       <order_id>123</order_id>       <order_action_dt>27-06-2020 07.00</order_action_dt>       <action_name>ordered</action_name>     </order_action>     <order_action>       <order_id>123</order_id>       <order_action_dt>27-06-2020 09.00</order_action_dt>       <action_name>dispatched</action_name>     </order_action>     <order_action>       <order_id>123</order_id>       <order_action_dt>27-06-2020 15.00</order_action_dt>       <action_name>delivered</action_name>     </order_action>     <order_action>       <order_id>234</order_id>       <order_action_dt>27-06-2020 07.30</order_action_dt>       <action_name>ordered</action_name>     </order_action>     <order_action>       <order_id>234</order_id>       <order_action_dt>27-06-2020 09.50</order_action_dt>       <action_name>dispatched</action_name>     </order_action>   </order_actions> </report>  <!-- language: lang-xml -->   Here's my XSLT Code   

enter image description here

What I would like to do is Group them Like below but not sure how.

enter image description here


UPDATE: Trying to add the XSLT Code but I’m getting an error enter image description here

UPDATE 2: After Adding xsl:apply-template inside for-each

<xsl:for-each select="order">           <table border="1">              <tr>               <td>                 ORDER_ID               </td>               <td>                 <xsl:value-of select="order_id"/>               </td>               <td>                 ORDER_NAME               </td>               <td>                 <xsl:value-of select="order_name"/>               </td>             </tr>             <xsl:apply-templates select="/report/order_actions/order_action[order_id = ./order_id]" />            </table>          </xsl:for-each> 

enter image description here

When I add the xsl-template after xsl:apply-templates

<xsl:for-each select="order">       <table border="1">          <tr>           <td>             ORDER_ID           </td>           <td>             <xsl:value-of select="order_id"/>           </td>           <td>             ORDER_NAME           </td>           <td>             <xsl:value-of select="order_name"/>           </td>         </tr>         <xsl:apply-templates select="/report/order_actions/order_action[order_id = ./order_id]" />         <xsl:template match="order_action" >           <tr>            </tr>         </xsl:template>       </table>      </xsl:for-each> 

enter image description here

UPDATE 3: So I added the xsl:apply-templates like so

 <xsl:for-each select="order">           <table border="1">              <tr>               <td>                 ORDER_ID               </td>               <td>                 <xsl:value-of select="order_id"/>               </td>               <td>                 ORDER_NAME               </td>               <td>                 <xsl:value-of select="order_name"/>               </td>             </tr>                 <xsl:apply-templates select="/report/order_actions/order_action[order_id = ./order_id]" />            </table>          </xsl:for-each> 

Then added a new template outside the first template

<xsl:template match="order_action">      <tr xmlns="http://www.w3.org/1999/xhtml">       <td>Order Status</td>       <td>         <xsl:value-of select="action_name"/>       </td>     </tr>     <tr xmlns="http://www.w3.org/1999/xhtml">       <td>Order Date</td>       <td colspan="">         <xsl:value-of select="order_action_dt"/>       </td>     </tr>       </xsl:template> 

The problem now is it’s showing all the order_action per order_id

enter image description here

Add Comment
1 Answer(s)

Following your code for the header row, you could achieve this by an

<xsl:apply-templates select="/report/order_actions/order_action[order_id = current()/order_id]" />

As well as a template to create the order action rows:

<xsl:template match="order_action" > <tr> ....your code here </tr> </xsl:template> 

The select on apply-templates filters the node-set of order_actions to those which match the order by id before invoking the template. The second template runs once per order_action in this node-set.

You may also want to sort them by the date they occurred, assuming they don’t necessarily appear in the document in date order. In which case, add an

<xsl:sort select="order_action_dt" order="descending" />

inside the apply-templates.

edit:

I mistakenly used the shorthand for the context node . and not the current node current() – where the context node changes inside an XPath selector because it is evaluating a node-set and each one in turn becomes the context node. The current node is the node currently in scope for the template. Replacing ./order_id for current()/order_id should get you what you want.

Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.