Translate

Archives

Manipulating XML Attributes using XSLT

Consider the following XML document called example.xml. As you can see, the document has two elements named sourcefield which contain multiple attributes.

<source>
   <sourcefield businessname ="" datatype ="DATE" description ="" fieldnumber ="1"
      fieldproperty ="0" fieldtype ="ELEMITEM" hidden ="NO" keytype ="NOT A KEY" length ="19"
      level ="0" name ="BUSINESS_DATE" nullable ="NULL" occurs ="0" offset ="0" physicallength ="19"
      physicaloffset ="0" picturetext ="" precision ="19" scale ="0" usage_flags =""/>
   <sourcefield businessname ="JOHNSON" datatype ="DATE" description ="SHOEMAKER" fieldnumber ="1"
      fieldproperty ="1" fieldtype ="ELEMITEM" hidden ="NO" keytype ="NOT A KEY" length ="19"
      level ="3" name ="BUSINESS_DATE" nullable ="NULL" occurs ="0" offset ="0" physicallength ="19"
      physicaloffset ="0" picturetext ="" precision ="19" scale ="0" usage_flags ="jj"/>
</source>


Suppose you wish to convert the contents of the sourcefield elements into CSV (Comma Separated Values) using XSLT.

This stylesheet (example1.xsl) is one way of transformating the above XML document:

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

<xsl:output method="text" encoding="iso-8859-1"/>

<xsl:strip-space elements="*" />

  <xsl:template match="*">
     <xsl:copy>
        <xsl:for-each select="@*">
           <xsl:if test="position() != last()"> "<xsl:value-of select="normalize-space(.)"/>",</xsl:if>
           <xsl:if test="position() = last()">"<xsl:value-of select="normalize-space(.)"/>"<xsl:text>&#10;</xsl:text>
      </xsl:if>
        </xsl:for-each>
        <xsl:apply-templates />
     </xsl:copy>
  </xsl:template>

</xsl:stylesheet>


Here is the output of the transformation of example.xml using the above stylesheet.

$ xstlproc example1.xsl example.xml
 "", "DATE", "", "1", "0", "ELEMITEM", "NO", "NOT A KEY", "19", "0", "BUSINESS_DATE", "NULL", "0", "0", "19", "0", "", "
19", "0",""
 "JOHNSON", "DATE", "SHOEMAKER", "1", "1", "ELEMITEM", "NO", "NOT A KEY", "19", "3", "BUSINESS_DATE", "NULL", "0", "0",
"19", "0", "", "19", "0","JJ"

Suppose that instead of converting the attributes into CVS data, you wished to convert them into elements.

Here is a stylesheet that will do exactly that:

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

   <xsl:output indent="yes" />

   <xsl:strip-space elements="*" />

   <xsl:template match="*">
       <xsl:copy>
           <xsl:if test="@*">
               <xsl:for-each select="@*">
                  <xsl:element name="{name()}">
                      <xsl:value-of select="." />
                  </xsl:element>
               </xsl:for-each>
           </xsl:if>
           <xsl:apply-templates />
       </xsl:copy>
  </xsl:template>

</xsl:stylesheet>


and here is the output of the transformation of example.xml using that stylesheet.

$ xsltproc example2.xsl example.xml
<?xml version="1.0"?>
<source>
  <sourcefield>
    <businessname></businessname>
    <datatype>DATE</datatype>
    <description></description>
    <fieldnumber>1</fieldnumber>
    <fieldproperty>0</fieldproperty>
    <fieldtype>ELEMITEM</fieldtype>
    <hidden>NO</hidden>
    <keytype>NOT A KEY</keytype>
    <length>19</length>
    <level>0</level>
    <name>BUSINESS_DATE</name>
    <nullable>NULL</nullable>
    <occurs>0</occurs>
    <offset>0</offset>
    <physicallength>19</physicallength>
    <physicaloffset>0</physicaloffset>
    <picturetext></picturetext>
    <precision>19</precision>
    <scale>0</scale>
    <usage_flags></usage_flags>
  </sourcefield>
  <sourcefield>
    <businessname>JOHNSON</businessname>
    <datatype>DATE</datatype>
    <description>SHOEMAKER</description>
    <fieldnumber>1</fieldnumber>
    <fieldproperty>1</fieldproperty>
    <fieldtype>ELEMITEM</fieldtype>
    <hidden>NO</hidden>
    <keytype>NOT A KEY</keytype>
    <length>19</length>
    <level>3</level>
    <name>BUSINESS_DATE</name>
    <nullable>NULL</nullable>
    <occurs>0</occurs>
    <offset>0</offset>
    <physicallength>19</physicallength>
    <physicaloffset>0</physicaloffset>
    <picturetext></picturetext>
    <precision>19</precision>
    <scale>0</scale>
    <usage_flags>jj</usage_flags>
  </sourcefield>
</source>
$

Enjoy!
 

Comments are closed.