69

I have an XML document with a default namespace indicated at the root. Something like this:

<MyRoot xmlns="http://www.mysite.com">
   <MyChild1>
       <MyData>1234</MyData> 
   </MyChild1> 
</MyRoot>

The XSLT to parse the XML does not work as expected because of the default namespace, i.e. when I remove the namespace, everything works as expected.

Here is my XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:template match="/" >
  <soap:Envelope xsl:version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
     <NewRoot xmlns="http://wherever.com">
       <NewChild>
         <ChildID>ABCD</ChildID>
         <ChildData>
            <xsl:value-of select="/MyRoot/MyChild1/MyData"/>
         </ChildData>
       </NewChild>
     </NewRoot>
   </soap:Body>
  </soap:Envelope>
 </xsl:template>
</xsl:stylesheet>

What needs to be done with XSLT document so that translation works properly? What exactly needs to be done in XSLT document?

1
  • ABCD is not valid XSLT. I think you need to Control-K the code. Commented Aug 28, 2009 at 17:49

3 Answers 3

78

You need to declare the namespace in your XSLT, and use it in XPath expressions. E.g.:

<xsl:stylesheet ... xmlns:my="http://www.mysite.com">

   <xsl:template match="/my:MyRoot"> ... </xsl:template>

</xsl:stylesheet>

Note that you must provide some prefix if you want to refer to elements from that namespace in XPath. While you can just do xmlns="..." without the prefix, and it will work for literal result elements, it won't work for XPath - in XPath, an unprefixed name is always considered to be in namespace with blank URI, regardless of any xmlns="..." in scope.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for answer. It is similar to what I have found in internet, but it does not work. My XML output still does not work as expected. If I remove the default namespace from source XML then output XML looks fine. My appl'n that does the XSLT translation is a .NET 2.0 application, if that makes a difference.
Please show your XLST that doesn't work, then. It's hard to say anything more definite without seeing it. What you describe still sounds like you missed the namespace qualifier somwhere. For example, keep in mind that you have to repeat it for every XPath step - i.e. /my:MyRoot/my:foo/my:bar.
Really useful note about needing a prefix. This triggered me to check the specs. It looks like, XPath would respect a default namepace if one were present, but XSLT explicitly excludes the default namespace from being in scope w3.org/TR/xslt#section-Expressions
@PavelMinaev: I used /my:MyRoot in my xPath so my template match looks like this: <xsl:template match="/my:MyRoot"> - so what is the MyRoot - is that a reserved name in XSLT?
No, it's just an element name. You should use whatever is the name of the outermost element for your XML there.
39

If you use XSLT 2.0, specify xpath-default-namespace="http://www.example.com" in the stylesheet section.

Comments

4

If this was kind of name space problem, there is room to try to modify two things in the xslt file:

  • add "my" name space definition in xsl:stylesheet tag
  • use "my:" prefix when call elements in traversing the xml file.

result

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="http://www.w3.org/2001/XMLSchema">
    <xsl:template match="/" >
        <soap:Envelope xsl:version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
            <soap:Body>
                <NewRoot xmlns="http://wherever.com">
                    <NewChild>
                        <ChildID>ABCD</ChildID>
                        <ChildData>
                            <xsl:value-of select="/my:MyRoot/my:MyChild1/my:MyData"/>
                        </ChildData>
                    </NewChild>
                </NewRoot>
            </soap:Body>
        </soap:Envelope>
    </xsl:template>
</xsl:stylesheet>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.