XSLT with XML source that has a default namespace set to xmlns
Solution 1
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.
Solution 2
If you use XSLT 2.0, specify xpath-default-namespace="http://www.example.com"
in the stylesheet
section.
Solution 3
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>
Larry
Updated on July 08, 2022Comments
-
Larry almost 2 years
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?
-
Larry over 14 yearsThanks 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.
-
emen over 9 yearsReally 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
-
Our Man in Bananas over 9 years@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? -
Pavel Minaev over 9 yearsNo, it's just an element name. You should use whatever is the name of the outermost element for your XML there.