19 October 2006

XSL FTW!

Just got a new project at work. We need to interface to another company's information system, and they want us to use web services. OK, cool, I'm all about the SOA (or will be once I do a little research), let's see what they've got. Interface specs, XML-RPC, all looks good until I get to the sample data they're sending. All their data is expressed as XML attributes. I know there's no hard consensus on elements vs. attributes, but I personally hold to the idea that attributes are for meta-data, and data itself should be in elements. I tried to ignore it, but it kept bugging me. I know that for the project I'm on, I'll just wind up working with what they give me, and suck it up. But I deperately wanted to convert it. Hey, it should be easy with XSL, right? Well, I suppose if you actually knew XSL, it probably would be. It took me a couple of hours to figure out the proper incantations of selectors and elements to get it done, but finally I did. And just on the off chance there's some other attribute-hater out there, here it is (sorry about the formatting!):

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

<xsl:template match="*">
<xsl:variable name="tagName" select="name()"/>
<xsl:element name="{$tagName}">
<xsl:text>
</xsl:text>
<xsl:for-each select="@*">
<xsl:variable name="tagName" select="name()"/>
<xsl:element name="{$tagName}"><xsl:value-of select="."/></xsl:element>
<xsl:text>
</xsl:text>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>

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

</xsl:stylesheet>

Invoke it with Xalan (or your XSLT processor of choice). I use the command "java org.apache.xalan.xslt.Process -in stuff.xml -xsl cvtAttrs.xsl" (where the script is in 'cvtAttrs.xsl', of course).

Share and enjoy!

No comments: