如何使用xslt处理xml命名空间的存在与否

时间:2010-04-16 11:52:46

标签: xslt namespaces xml-namespaces

我有一些XML / TEI文档,我正在编写一个XSLT 2.0来提取其内容。

几乎所有TEI文档都没有命名空间,但其中一个具有默认命名空间(xmlns="http://www.tei-c.org/ns/1.0")。 因此,所有文档都具有相同的方面,包括<TEI><teiHeader>等未经验证的标记,但如果我尝试提取内容,则所有文档都使用“非命名空间文档”,但没有(当然)从命名空间文档中提取。

所以我使用了属性xpath-default-namespace="http://www.tei-c.org/ns/1.0",现在(当然)唯一有效的文件就是命名空间。

我根本无法编辑文档,所以我要问的是,是否有一种方法可以动态更改xpath-default-namespace,以便使//teiHeader的工作xpath像命名空间和非命名空格一样命名空间文件

3 个答案:

答案 0 :(得分:1)

没有一种干净的方法可以准确地按照你的要求去做。但是,有可用的解决方法。您可以使用两阶段流程,从文档中删除命名空间(如果存在),然后将其传递给所有内容的相同模板。

DocBook XSLT中有一个很好的例子(在XSLT 1中)。看一下html / docbook.xsl和common / stripns.xsl

基本上,您需要将删除命名空间的结果分配给变量,然后调用现有模板(对于非命名空间)但选择变量。

答案 1 :(得分:1)

这很难看,但这会给你你想要的东西

//*[name()='teiHeader']

如果对任何XPath表达式中的所有位置步骤使用此样式,则XPath表达式将仅按名称选择元素,无论这些元素是否属于任何名称空间。

答案 2 :(得分:1)

如果您使用的是 XSLT 2.0 ,那么您可以选择在节点测试中为命名空间配置通配符。

e.g。 //*:teiHeader

http://www.w3.org/TR/xpath20/#node-tests

  

节点测试也可以有表格   *:NCName来。在这种情况下,节点测试对于主体的任何节点都为真   步长轴的节点种类,其本地   name匹配给定的NCName,   无论其命名空间或缺乏   命名空间。

这在功能上等同于Dimitre Novatchev的例子,但更短/更容易打字。

但是,这只适用于XSLT / XPATH 2.0