1

I'm trying to use XSLT to transform an XML document into a CSV. The problem I'm running into is that having an "xmlns" attribute makes certain things difficult to impossible to work with.

Here is a simplified example of what works, first.

XML:

<a>
  <b>B</b>
  <c>
    <d>D1</d>
    <d>D2</d>
  </c>
</a>

XSL:

<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8"/>

<xsl:template match="/a">

    <xsl:for-each select="c/d">
        <xsl:value-of select="../../b"/>,<xsl:value-of select="."/>
        <xsl:text>&#xA;</xsl:text>
    </xsl:for-each>

</xsl:template>
</xsl:stylesheet>

results in the correct output

B,D1
B,D2

However, merely adding the xmlns attribute at the top

<a xmlns="http://example.com">
  <b>B</b>
  <c>
    <d>D1</d>
    <d>D2</d>
  </c>
</a>

results in the default behavior of just printing out the leaf node contents (which happens when no matching succeeds), rather than producing the CSV as intended.

I was able to get partial success like so

<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8"/>

<xsl:template match="*[local-name() = 'a']">

    <xsl:value-of select="*[local-name() = 'b']"/><xsl:text>&#xA;</xsl:text> <!-- Works -->

    <xsl:for-each select="*[local-name() = 'c/d']"> <!-- Does not work -->
        <xsl:value-of select="."/>
        <xsl:text>&#xA;</xsl:text>
    </xsl:for-each>

</xsl:template>
</xsl:stylesheet>

however as the comment indicates the for-each doesn't match at all, this just prints "B".

I cannot change the XML. In theory I could use sed or something to remove the xmlns attribute, but I'd ideally like to avoid that as the input XML file is many gigabytes.

How can I adapt my simplified code to work when the xmlns attribute is present?

micseydel
  • 381
  • 6
  • 13

1 Answers1

2

You need to declare the default namespace in your xslt. See this:

XSLT with XML source that has a default namespace set to xmlns

Steve Boyd
  • 1,287
  • 11
  • 17
  • I read that question and somehow didn't ingest it. Thanks for the super fast reply, that question+solution solved my problem! – micseydel Feb 14 '19 at 18:52