How to flatten the XML

jn93 671 Reputation points
2024-07-03T09:51:20.1633333+00:00

Hi have a complex XML structured as per attached below. How can I flatten the XML using XSLT? I have attached the expected sample flatten xml(expected_ouput_flat_oder_xml.xml) based on the complex xml(Order_xml.xml) I provided. I have tried using the XSLT code I written but I didnt get the output I want. I have shown below the XLST I wrote as well for your reference. Anyone able to help me with this? Appreciate the response.

expected_ouput_flat_oder_xml.xml

Order_xml.xml

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

<xsl:template match="/Orders"> <Orders> <xsl:for-each select="Order"> <xsl:variable name="orderID" select="OrderID"/> <xsl:variable name="customerID" select="CustomerID"/> <xsl:variable name="orderDate" select="OrderDate"/>

    <xsl:for-each select="OrderDetails/Detail">
      <xsl:variable name="productID" select="ProductID"/>
      <xsl:variable name="quantity" select="Quantity"/>
	  
	<xsl:for-each select="../..//ShippedRemarks">
    <xsl:variable name="ShipID" select="ShipID"/>   
    <xsl:variable name="ShipQuantity" select="ShipQuantity"/>   		
    
	<xsl:for-each select="../../..//DetailName">
      <xsl:variable name="productName" select="ProductName"/>  
      <xsl:variable name="PaymentReqDate" select="PaymentReqDate"/>  
      <xsl:variable name="PaymentAmt" select="PaymentAmt"/>  
      <xsl:variable name="PaymentMode" select="PaymentMode"/>  
      
      <xsl:for-each select="../..//PaymentInfo">		  
	    <Order>
          <OrderID><xsl:value-of select="$orderID"/></OrderID>
          <CustomerID><xsl:value-of select="$customerID"/></CustomerID>
          <OrderDate><xsl:value-of select="$orderDate"/></OrderDate>
          <ProductID><xsl:value-of select="$productID"/></ProductID>
          <Quantity><xsl:value-of select="$quantity"/></Quantity>
          <ShipID><xsl:value-of select="$ShipID"/></ShipID>		
          <ShipQuantity><xsl:value-of select="$ShipQuantity"/></ShipQuantity>					  
          <ProductName><xsl:value-of select="$productName"/></ProductName>			  
          <PaymentVchNo><xsl:value-of select="PaymentVchNo"/></PaymentVchNo>	
          <PaymentReqDate><xsl:value-of select="PaymentReqDate"/></PaymentReqDate>	
          <PaymentAmt><xsl:value-of select="PaymentAmt"/></PaymentAmt>	
          <PaymentMode><xsl:value-of select="PaymentMode"/></PaymentMode>				  
        </Order>
      </xsl:for-each>			
      </xsl:for-each>
     </xsl:for-each>          
    </xsl:for-each>
  </xsl:for-each>
</Orders>

</xsl:template> </xsl:stylesheet>

XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
785 questions
0 comments No comments
{count} votes

Accepted answer
  1. Viorel 114.1K Reputation points
    2024-07-03T11:29:10.0866667+00:00

    Try this:

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml" indent="yes"/>
    
        <xsl:template match="/Orders">
            <Orders>
                <xsl:apply-templates select="Order"/>
            </Orders>
        </xsl:template>
    
        <xsl:template match="Order">
            <xsl:variable name="o" select="."/>
            <xsl:variable name="pi" select="PaymentInfo"/>
    
            <xsl:for-each select="OrderDetails/Detail/ShippedRemarks">
                <xsl:variable name="shr" select="."/>
                <xsl:variable name="d" select=".."/>
    
                <xsl:for-each select="$o/ProductDetails/DetailName">
                    <xsl:variable name="dn" select="."/>
    
                    <Order>
                        <xsl:copy-of select="$o/OrderID | $o/CustomerID | $o/OrderDate"/>
                        <xsl:copy-of select="$d/ProductID | $d/Quantity"/>
                        <xsl:copy-of select="$shr/*"/>
                        <xsl:copy-of select="$dn/ProductName"/>
                        <xsl:copy-of select="$pi/*"/>
                    </Order>
    
                </xsl:for-each>
            </xsl:for-each>
        </xsl:template>
    
    </xsl:stylesheet>
    

    Instead of “*”, you can specify the names explicitly.


0 additional answers

Sort by: Most helpful