检测XML文件是否包含特定命名空间

时间:2010-10-01 11:14:05

标签: xslt xslt-1.0

再次简单的事情。我有一个解析XML和XSL文件的样式表。基本上,它试图检测XML是否是带有以下内容的样式表:

<xsl:if test="count(//xsl:template)!=0">

它确实检测到了样式表。但是,它存在XML文件问题,它会生成“未定义的命名空间前缀 - 'xsl'”错误。 (在XmlSpy中。我正在研究的项目中存在类似的错误。)

我做错了什么。有关如何改进此样式表的任何建议吗?


一些附加信息:这是一个样式表,用于分析其他XML文件,无论它们包含什么。它应该能够自我改造,并且做得很好。转换其他(普通)样式表也没有问题。当我尝试转换常规XML文件时,问题就出现了。然而,并非所有XML文件......


事实证明,错误是另一回事。我试图转换的XML文件包含一个处理指令。这一个:<?xml-stylesheet href="..\MyStylesheet.xsl" type="text/xsl"?>
我现在遇到的问题是,当我处理包含此PI的XML文件时,XSLT会开始报告有关未定义的名称空间前缀的错误。那么,我如何告诉XSLT处理器忽略这个处理指令呢?

3 个答案:

答案 0 :(得分:1)

仔细检查您如何声明xsl命名空间以及您选择的命名空间前缀。

如果要在XPATH表达式中使用xsl命名空间前缀,请确保在样式表中定义{/ 1}}命名空间前缀。当您尝试使用时,您将收到该错误尚未声明的名称空间前缀。

如果它没有在样式表中的任何地方声明(通常在文档元素上如下:<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">),或者您选择了不同的名称空间前缀(例如声明为“ xslt”) “喜欢这样:xmlns:xslt="http://www.w3.org/1999/XSL/Transform"),然后当您尝试引用” xsl “时,它将无法知道您所指的是什么。

您可以在xsl语句中声明if名称空间前缀作为快速测试:

<xsl:if test="count(//xsl:template)!=0" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  

有关如何改善这一点的任何建议   样式表?

您可以简化测试条件以选择xsl:template元素,而不是评估它们的count()。如果选择了某些内容,则test="//xsl:template"的结果将评估为true();如果未选择任何内容,则false()的结果将评估为xsl:template

在样式表中//是顶级构造,它们是文档元素的子元素。您可以使用更高效的XPATH表达式,而不是使用<xsl:if test="/*/xsl:template" /> 来递归XML文档树中的每个节点:

{{1}}

答案 1 :(得分:1)

假设XSLT代码文件始终包含<xsl:template>指令是不正确的。

有一些XSLT样式表模块的示例,其中文件只包含<xsl:stylesheet>指令和一个或多个全局级变量。此类样式表模块通常使用<xsl:import><xsl:include>指令导入/包含在另一个样式表模块中。

此外,定义XSLT的内容不是构成XSLT指令的元素的前缀。此前缀不强制为"xsl",并且某些程序员使用不同的前缀,例如"xslt""x"

真正定义XSLT代码的是XSLT命名空间

最后,即使包含<xsl:stylesheet>指令,也不保证XSLT代码文件,因为XSLT提供了同义词:<xsl:transform>

考虑到所有这些因素,更好的测试将是:

/*[contains('|stylesheet|transform|', concat('|', local-name(), '|')
          and
            namespace-uri()="http://www.w3.org/1999/XSL/Transform"
           )

因为有可能有embedded stylesheets ,所以上面的测试可以稍加修改以涵盖这些:

//*[contains('|stylesheet|transform|', concat('|', local-name(), '|')
          and
            namespace-uri()="http://www.w3.org/1999/XSL/Transform"
           )

答案 2 :(得分:0)

为什么需要检查“/ xsl:template | xsl:transform”之外的任何内容?这些必须位于顶层,并且位于顶层。