1
votes

I have following XML, elements are dynamically generated and can change from time to time, therefore I can't hard code field name,

 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
   <datacollection id="amazon_order.1">
   <table name="order_detail">
       <row name="default_options">
           <field name="zipCode">800227028</field>
           <field name="customerLastName">COMER</field>
           <field name="state">CO</field>
           <field name="city">COMMERCE CITY</field>
           <field name="serialNumber">818243CX601252Y</field>           
       </row>
     </table>
     </datacollection>

And want to transform it into following format using XSLT,

<datacollection id="amazon_order.1">
<table name="order_detail">
   <row name="default_options">
       <zipCode>800227028</zipCode>
       <customerLastName>COMER</customerLastName>
       <state>CO</state>
       <city>COMMERCE CITY</city>
       <serialNumber>818243CX601252Y</serialNumber>                      
   </row>
</table>
</datacollection>
1
So you want to convert each <field> element to an element named by the original element's name attribute, leaving everything else unchanged?John Bollinger
yes, everything should stay as is.pravin deore

1 Answers

2
votes

You want to transform <field> elements to output elements having variable names derived from the original elements' attributes. That calls for a template matching the original elements and creating corresponding new ones via an XSL element element. You want to keep everything else the same, so that calls for an identity transform to handle everything else, both outside and inside the erstwhile <field> elements.

Assuming that your <field> elements will never have attributes other than name that need to carry over to the result document, that would look like this:

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

  <!-- identity transform for otherwise-unmatched nodes and attributes -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>

  <!-- transform for field elements at any depth -->
  <xsl:template match="field">
    <xsl:element name="{@name}">
      <!-- transform this node's non-attribute children -->
      <xsl:apply-templates select="node()" />
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>