将XML导入到根节点上没有名称空间的XSL

时间:2017-07-31 17:20:44

标签: xml firefox xslt namespaces

我正在尝试使用XSL将两个XML文件转换为HTML。我有一切工作,但我有一个问题。其中一个XML文件包含我从中提取的各种信息。文件中的任何位置都没有名称空间声明,但我需要访问的节点是名称空间前缀。我最初的修复是将命名空间添加到根节点,但我发现我无法做到这一点,因为文件无法修改。

如果我关闭名称空间,我会在Firefox中获得以下内容:

XML Parsing Error: prefix not bound to a namespace

名称空间应该是(但不存在于源XML中):

xmlns:prop="http://www.blank.com/prop" 
xmlns:item="http://www.blank.com/item" 

我该如何解决这个问题?

XML:

<?xml version="1.0" encoding="UTF-8"?>
<collection>
  <prop:id>123</prop:id>
  <document>
    <item:name>Document</item:name>
  </document>
</collection>

XSL: (元素的价值都不起作用)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html"/>
  <xsl:variable name="propsPath" select="test_Props.xml"/>
  <xsl:variable name="props" select="document($propsPath)" />

  <xsl:template match="/">
    <html><body><div>
      <xsl:value-of select="$props/collection/*[local-name() = 'id']"/>
      <xsl:value-of select="$props/collection/prop:id"/>
    </div></body></html>
  </xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:1)

编辑:这篇文章没有解决具体问题。不过我把它留在这里,因为它举例说明了一般问题的解决方案。

我发现在不修改test_Props.xml的情况下绕过命名空间问题的一个解决方案是在存根文件中使用实体引用

所以你的test_Props.xml文件是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<collection>
  <prop:id>123</prop:id>
  <document>
    <item:name>Document</item:name>
  </document>
</collection>

现在围绕此内容创建一个名为test_Props_stub.xml的存根文件:

<?xml version="1.0"?>
<!DOCTYPE doc [
<!ENTITY otherFile SYSTEM "test_Props.xml">
]>
<root xmlns:prop="http://www.blank.com/prop" xmlns:item="http://www.blank.com/item">
&otherFile;
</root>

此解决方案的灵感来自this SO answer 然后,只需添加新的根节点即可修改document的名称及其在XSLT中的路径,并且您已完成:

<xsl:variable name="propsPath" select="'test_Props_stub.xml'"/>
<xsl:variable name="props" select="document($propsPath)/root" />

其余的可以保持不变 现在,存根文件的root节点的名称空间将应用于原始XML文件,并且XPath表达式匹配。

顺便说一下,你在下面一行中有一个小但讨厌的错误:

<xsl:variable name="propsPath" select="test_Props.xml"/>

你忘记了文件名周围的引号。