Pairing Off in XSLT

Pairing Off in XSLT

My friend Newton was just fighting to transform some XML that was structured in a awkward way.  The machine generated XML he was working with basically paired off successive elements, for example to provide a credential prompt and then the following element contained the credential itself.  It took a bit of fiddling to get the right XPath expression to perform the transformation.  I thought it would be illuminating to share it with you and hopefully someone will find a better solution than the one we came up with.

The Source

The source XML looked like this
<?xml version="1.0" encoding="UTF-8" ?>
<exampleElement>

    <AttributeElement>
        <DisplayElement>
            <SelectElement attribute1="A"/>
        </DisplayElement>
    </AttributeElement>

    <AttributeElement>
        <DisplayElement>
            <PasswordElement attribute1="1"/>
        </DisplayElement>
    </AttributeElement>
...
    <AttributeElement>
        <DisplayElement>
            <SelectElement attribute1="E"/>
        </DisplayElement>
    </AttributeElement>

    <AttributeElement>
        <DisplayElement>
            <PasswordElement attribute1="5"/>
        </DisplayElement>
    </AttributeElement>

</exampleElement>
Note the pairing of the Attribute elements.

The Target

The target XML looked like this
<?xml version = '1.0' encoding = 'UTF-8'?>
<exampleElement>

     <Attribute>
          <Select attribute1="A"/>
          <Password attribute1="1"/>
     </Attribute>
...
     <Attribute>
          <Select attribute1="E"/>
          <Password attribute1="5"/>
     </Attribute>
</exampleElement>

The Problem

The challenge was after identifying a path with a SelectElement element how to select the following path that had a PasswordElement element.

The Answer is Axis

The trouble with XSLT is that I don't do enough of it to remember all the tools available.  In this case it was very simple once I had remembered how axis work.  Here is my solution
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <exampleElement>
            <xsl:for-each select="/exampleElement/AttributeElement/DisplayElement/SelectElement">
                <Attribute>
                    <Select>
                        <xsl:attribute name="attribute1"><xsl:value-of select="@attribute1"/></xsl:attribute>
                    </Select>
                    <Password>
                        <xsl:attribute name="attribute1">
                    <xsl:value-of select="following::AttributeElement[1]/DisplayElement/PasswordElement/@attribute1"/>
            </xsl:attribute>
                    </Password>
                </Attribute>
            </xsl:for-each>
        </exampleElement>
    </xsl:template>
</xsl:stylesheet>
This solution iterates over all the SelectElement elements and then for each of those elements it picks out the following PasswordElement in the document.  It does this by using the XPath expression "following::AttributeElement[1]/DisplayElement/PasswordElement/@attribute1".
The "following::" axis selects all nodes in the document that come after the given SelectElement element.  This flattens the hierarchy enabling us to choose the next AttributeElement element by selecting the AtrributeElement element with index 1 (AttributeElement[1]).  We can then traverse that part of the XML using the normal child axis.  Simple when its done but when you rarely use axis other than the child axis it takes a while to remember how they work.

Reference

I find the two O'Reilly books on XSLT to be very helpful when struggling with XPath and XSLT.  These are the Doug Tidwell XSLT book and the Sal Mangano XSLT Cookbook.

I hope this saves sombody some time.

Comments:

Post a Comment:
Comments are closed for this entry.
About

Musings on Fusion Middleware and SOA Picture of Antony Antony works with customers across the US and Canada in implementing SOA and other Fusion Middleware solutions. Antony is the co-author of the SOA Suite 11g Developers Cookbook, the SOA Suite 11g Developers Guide and the SOA Suite Developers Guide.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today