XSLT Transform XML with Namespaces
Asked Answered
A

2

52

I'm trying to transform some XML into HTML using XSLT.

Problem:

I can't get it to work. Can someone tell me what I'm doing wrong?

XML:

<ArrayOfBrokerage xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.test.com/">
    <Brokerage>
        <BrokerageID>91</BrokerageID>
        <LastYodleeUpdate>0001-01-01T00:00:00</LastYodleeUpdate>
        <Name>E*TRADE</Name>
        <Validation i:nil="true" />
        <Username>PersonalTradingTesting</Username>
    </Brokerage>
</ArrayOfBrokerage>

XSLT:

<xsl:stylesheet version="1.0" xmlns="http://www.test.com/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xslFormatting="urn:xslFormatting">

    <xsl:output method="html" indent="no"/>

    <xsl:template match="/ArrayOfBrokerage">
        <xsl:for-each select="Brokerage">
            Test
       </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>
Allotment answered 13/11, 2009 at 17:52 Comment(0)
R
73

You need to provide a namespace prefix in your xslt for the elements you are transforming. For some reason (at least in a Java JAXP parser) you can't simply declare a default namespace. This worked for me:

<xsl:stylesheet version="1.0" xmlns:t="http://www.test.com/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xslFormatting="urn:xslFormatting">

    <xsl:output method="html" indent="no"/>

    <xsl:template match="/t:ArrayOfBrokerage">
        <xsl:for-each select="t:Brokerage">
            Test
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

This will catch everything that is namespaced in your XML doc.

Revkah answered 13/11, 2009 at 18:11 Comment(6)
This worked for me too in testing (running XSLT debug in Visual Studio 2008)Blabber
This did the trick. I had tried this with the combination of exclude-result-prefixes="t" because I thought it would allow me to not have to tack on t: before each node. Is there any way to avoid having to do this?Allotment
You could match elements using the local-name(), for instance: template match="/*[local-name()='ArrayOfBrokerage']"Mothering
thanks, this worked for me too. it's still a bit ungainly having to jam these namespaces in everywhere - wish there was a better way.Ootid
With xslt 2.0 you can use the xpath-default-namespace attribute in the stylesheet declaration, e.g. like <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://example.com/some-namespace"> ... Holliholliday
Might be worth noting that nested elements need namespace prefixes as well, e.g. match="/t:Brokerage/t:SomeChild/t:SomeGrandchild"Synchronize
A
-2

How do you execute the transformation? Maybe you forgot to link the XSLT stylesheet to XML document using:

<?xml-stylesheet type="text/xsl" href="cdcatalog.xsl"?>

at the beginning of XML document. More explanation here.

Archaimbaud answered 13/11, 2009 at 18:0 Comment(1)
I'm not sure what you mean by this. I'm actually not doing a transform on an XML file but rather serializing a business object using the DataContractSerializer and specifying the namespace in the DataContract of the object.Allotment

© 2022 - 2024 — McMap. All rights reserved.