修改xslt是名称空间不可知的

时间:2009-02-03 16:30:38

标签: xml xslt xpath xml-namespaces

我有一个我创建的XSLT来处理特定的xml文档。但是,现在名称空间正在某些文档中引入,但并非所有文档都引入了名称空间。我想对这些文档使用相同的XSLT,但是我无法将样式表修改为名称空间无关。

之前曾建议将我的xpath修改为*[local-name()="ElementName"],但考虑到我们已经制作了样式表,这是非常耗费人力的。

此外,我知道我可以将xpath-default-namespace设置为特定的命名空间,但如前所述,我不能简单地将其设置为#all或可能的命名空间列表。我正在寻找更有效的解决方案,并且可以使用Saxon处理器的扩展功能。有任何想法吗?感谢。

4 个答案:

答案 0 :(得分:3)

您是否考虑过预处理XML文档?

您可以删除所有名称空间(注意可能的冲突),然后使用现有的XSL转换处理它。

这种方法的优点是您根本不必修改XSLT。它保持可读性(* [local-name()='frob']看起来非常糟糕)并且可维护。

答案 1 :(得分:1)

经过进一步的咨询,似乎没有简单的方法可以解决这个问题。必须重新设计XSLT以使命名空间无关,或使用xpath-default-namespace元素上的<xsl:stylesheet>属性。如果我们希望保留传入文档的命名空间但仍有一个样式表可以使用多个命名空间,那么我们的模板需要类似于以下形式:

<xsl:template match="*[local-name(.)='ElementName']">
   <xsl:element name="{local-name(.)}" xmlns="http://yourURIhere">
      <xsl:value-of select="."/>
   </xsl:element>
</xsl:template/>

答案 2 :(得分:1)

也许我不明白你的问题,但是你不能只让你的模板匹配null-namespace版本元素的命名空间版本? - 像这样:

<xsl:template match="ElementName | NS:ElementName" xmlns:NS="your-namespace">
   ... output ...
</xsl:template>

(通常,NS前缀的声明将放在样式表元素上)

这对我来说是迄今为止最“干净”的版本 - 我已经使用它来使用单个XSLT样式表处理所有三种RSS格式(0.91,1.0和2.0)。

答案 3 :(得分:0)

我发现以下页面很好地展示了问题,但没有提供解决方案:

http://www.edankert.com/defaultnamespaces.html

我在O'Reilly的“XML in a Nutshell”中找到了解决这个问题的方法:

http://docstore.mik.ua/orelly/xml/xmlnut/ch08_10.htm