再次简单的事情。我有一个解析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处理器忽略这个处理指令呢?
答案 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”之外的任何内容?这些必须位于顶层,并且仅位于顶层。