如何在引用其他文档时覆盖默认命名空间

时间:2015-12-03 14:59:33

标签: xslt xpath

我有两个名为foo.xml的输入文档,bar.xml定义如下

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/>

和我的XSLT(使用XSL 2.0)命名为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>

如果我现在运行XSLT,则会发生

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

那是&#34;没有&#34;。

但如果我删除该行

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

重新运行我得到这个

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

我的问题只是,我该如何保留

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

在我的XSLT中仍然得到输出&#34; MyClassName&#34;没有修改文件foo.xml和bar.xml?

2 个答案:

答案 0 :(得分:1)

你可以改变:

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

为:

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

这将在任何命名空间中选择class。更合适的解决方案会将选择范围缩小到仅在非命名空间中的class

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

答案 1 :(得分:0)

有关如何调整XPath以匹配元素的一些选项:

  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()='']