Re: Output from node traversal not processing correctly

Nathan Nadeau <[email protected]> Wed, 17 Feb 2010 14:41:31 -0500
Newsgroups gmane.text.xml.xalan.java.user
Organization Gleim Publications
Message-ID <[email protected]>
Tim Hibbs wrote:
> Second, with changes you implied in your response, I tried several 
> variations. I'm still missing something, probably elemental, of 
> importance. Additional guidance would be most welcome... 
>  
> I now have the following, representative of all the variations I tried:
> *_XML_*: (no change)
>  
> *_XSL_*:
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet version="1.0" 
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
> xmlns="http://www.fedex.com/schemas/freightRateQuotation">
>  <xsl:template match="/">
>   <html>
>    <body>
>      <xsl:apply-templates select="To" />
>    </body>
>   </html>
>  </xsl:template>
>  
>  <xsl:template match="To">
>   To: <xsl:value-of select="."/>
>  </xsl:template>
> </xsl:stylesheet>
>  
You have two issues now that I can see:

1) Declaring the default namespace using xmlns="xyz" in your XSL does 
not actually affect element names listed in XPath expressions (the 
select="To" in your <xsl:apply-templates> is an XPath expression). If an 
element in an XPath expression does not have an explicit namespace 
prefix, XPath assumes the null namespace, NOT the default namespace. 
Therefore it is not finding any null namespace <To> elements in your 
input XML, since your XML only contains <To> elements in the 
http://www.fedex.com/schemas/freightRateQuotation namespace.

You need to use an explicit namespace declaration in your XSL such as 
xmlns:fedex="http://www.fedex.com/schemas/freightRateQuotation", and 
then use <xsl:apply-templates select="fedex:To"/> and <xsl:template 
match="fedex:To">

2) The XPath you're using in the <apply-templates/> statement actually 
will not find the <To> element in your XML. This is because select="To" 
is equivalent to select="child::To", which means you're telling it to 
look for children elements of the current context node named <To>. 
However your current context node is the document itself because you're 
in the match="/" template. There are no direct children <To> elements 
for the location you're at in your input document. You need to fix your 
XPath so that it can find the elements you want, or alter your context 
node so that it does contain the <To> element as a child.

For example you could use select="//fedex:To" or 
select="descendant::fedex:To" or 
select="fedex:tFreightRateQuotation/fedex:CommonData/fedex:To".

Good Luck,
Nathan