user3721979
user3721979

Reputation: 43

How to override default namespace when refering to another document

I have two input documents called foo.xml and bar.xml defined like this

foo.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<foo:IMM-contents xmlns:foo="http://whatever"
                  xmlns:xs="http://www.w3.org/2001/XMLSchema">
<class name="MyClassName"/>
</foo:IMM-contents>

bar.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<bar/>

and my XSLT (using XSL 2.0) named foobar.xsl

<?xml version="1.0" ?>
<xsl:stylesheet version="2.0"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:foo="http://whatever"
                xpath-default-namespace="urn:something:*"
            >
  <xsl:output method="text"
              encoding="utf8"
              />

  <xsl:param name="fooFile" select="'foo.xml'"/>

  <xsl:variable name="fooDoc" select="document($fooFile)"/>

  <xsl:template match="/">
    <xsl:for-each select="$fooDoc/foo:IMM-contents/class">
      <xsl:value-of select="@name"/>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

If I now run the XSLT this happens

$ java -jar saxon9he.jar bar.xml -xsl:foobar.xsl
$

That is "nothing".

But if I remove the line

xpath-default-namespace="urn:something:*"

from the XSLT and re-run I get this

$ java -jar saxon9he.jar bar.xml -xsl:foobar.xsl
MyClassName$

My question is simply, how can I retain the line

xpath-default-namespace="urn:something:*"

in my XSLT and still get the output "MyClassName" without modifying files foo.xml and bar.xml?

Upvotes: 1

Views: 626

Answers (2)

Mads Hansen
Mads Hansen

Reputation: 66783

A few options for how to adjust your XPath to match the class element:

  1. $fooDoc/foo:IMM-contents/*:class
  2. $fooDoc/foo:IMM-contents/*:class[namespace-uri()='']
  3. $fooDoc/foo:IMM-contents/*:class[not(namespace-uri())]
  4. $fooDoc/foo:IMM-contents/*[local-name()='class']
  5. $fooDoc/foo:IMM-contents/*[local-name()='class' and namespace-uri()='']

Upvotes: 0

michael.hor257k
michael.hor257k

Reputation: 117073

You could change:

<xsl:for-each select="$fooDoc/foo:IMM-contents/class">

to:

<xsl:for-each select="$fooDoc/foo:IMM-contents/*:class">

That will select class in any namespace. A more proper solution would narrow the selection down to class in no-namespace only:

<xsl:for-each select="$fooDoc/foo:IMM-contents/*:class[not(namespace-uri())]">

Upvotes: 1

Related Questions