Lumpy
Lumpy

Reputation: 115

XSL element attribute lookup across elements in the xml by cross reference

Fairly new to xslt, and was hoping to be able to do attribute value lookups in other elements when walking through the xpath. I have an xml I need to process and grab values from. Basically I want to get an attribute value and find the element(s) that contain that value and grab the underlying child's element.

My xml structure is this:

<root>
<first>
    <second>
        <third>  
            <county>
                 <districts>
                                <district>
                                    <cityTaxCode zip="01234" />
                                    <cityTaxCode zip="56789" />
                                </district>
                        </districts>
                    </county>

            <schoolDistricts>
                        <schoolTaxId zipid="01234">
                                <locality>
                                    upper
                                </locality>
                                <county>
                                    <value>east-highland</value>
                                </county>
                        </schoolTaxId>
                        <schoolTaxId zipid="56789">
                            <locality>
                                    lower
                                </locality>
                            <county>
                                    <value>west-highland</value>
                            </county>
                        </schoolTaxId>
                    </schoolDistricts>
        </third>
    </second>   
</first>
</root>

The output I wished for is:

County

 - district | zip: 01234 | east-highland
 - district | zip: 56789 | west-highland

I tried using the xsl key element lookup but every time it runs, I get blank results like this:

County

 - district 
 - district 

My xslt looks like this:

 <xsl:key name="zipLookup" match="root/first/second/third/schoolDistricts/schoolTaxId" 
use="@zipid"/>

 <xsl:template match="root/first/second/third/county/districts/district/cityTaxCode" >

<xsl:element name="County">
    County  

        <xsl:for-each select="key('zipLookup', @zip)">      
            <xsl:apply-templates select="*/county" />
        </xsl:for-each>
    </xsl:element>        
</xsl:template>


<xsl:template match="county">   
     <xsl:element name="Value">
        <xsl:value-of select="@value"/>
     </xsl:element>
</xsl:template>

For some reason, it works until it can't find the other "county" element in the sibling element that are both children of the third element node. Any help would be appreciated. Thanks!

Upvotes: 0

Views: 536

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 116993

You show a text output, yet your stylesheet produces XML - that's kind of confusing.

See if the following stylesheet can help:

XSLT 1.0

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

<xsl:key name="zipLookup" match="schoolTaxId" use="@zipid"/>

<xsl:template match="/root" >
    <root>
        <xsl:apply-templates select="first/second/third/county/districts/district/cityTaxCode" />
    </root>        
</xsl:template>

<xsl:template match="cityTaxCode" >
    <zone zip="{@zip}">
        <xsl:apply-templates select="key('zipLookup', @zip)" />
    </zone>        
</xsl:template>

<xsl:template match="schoolTaxId">   
     <county>
        <xsl:value-of select="county/value"/>
     </county>
</xsl:template>

</xsl:stylesheet>

Applied to your example input (after correcting a typo) produces:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <zone zip="01234">
      <county>east-highland</county>
   </zone>
   <zone zip="56789">
      <county>west-highland</county>
   </zone>
</root>

Upvotes: 1

Related Questions