检测 XML 文件是否包含特定命名空间
又是一件简单的事情。我有一个解析 XML 和 XSL 文件的样式表。基本上,它尝试检测 XML 是否是样式表:
<xsl:if test="count(//xsl:template)!=0">
它确实检测样式表。但 XML 文件存在问题,会生成“未定义的命名空间前缀 - 'xsl'”错误。 (在 XmlSpy 中。我正在处理的项目中也出现类似错误。)
我做错了。关于如何改进这个样式表有什么建议吗?
一些附加信息:这是一个样式表,用于分析其他 XML 文件,无论它们包含什么内容。它甚至应该能够自我转变,而且做得很好。转换其他(普通)样式表也没有问题。当我尝试转换常规 XML 文件时,问题就出现了。但并非所有 XML 文件...
事实证明,错误是其他的。我尝试转换的 XML 文件包含处理指令。这个:
我现在遇到的问题是,当我处理包含此 PI 的 XML 文件中,XSLT 开始报告有关未定义的命名空间前缀的错误。那么,如何告诉 XSLT 处理器忽略这条处理指令呢?
Again a simple thing. I have a stylesheet that parses XML and XSL files. Basically, it tries to detect if the XML is a stylesheet with:
<xsl:if test="count(//xsl:template)!=0">
It does indeed detect stylesheets. It has problems with XML files, though, which generate an "Undefined namespace prefix - 'xsl'" error. (In XmlSpy. Similar errors in the project I'm working on.)
I'm doing something wrong. Any suggestions on how to improve this stylesheet?
Some additional information: This is a stylesheet that's meant to analyse other XML files, no matter what they contain. It should be able to transform itself even, and does so nicely. It has no problem transforming other (normal) stylesheets either. The problem arrives when I try to transform a regular XML file. Yet not all XML files...
As it turns out, the error is something else. The XML files that I tried to transform contain a processing instruction. This one: <?xml-stylesheet href="..\MyStylesheet.xsl" type="text/xsl"?>
The problem I have now is that when I process an XML file that contains this PI, the XSLT starts reporting the error about the undefined namespace prefix. So, how do I tell the XSLT processor to ignore this processing instruction?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
仔细检查您如何声明
xsl
命名空间以及您选择的命名空间前缀。您需要确保
xsl
命名空间如果您想在 XPATH 表达式中使用前缀,则该前缀已在您的样式表中定义。 当您尝试使用尚未声明的名称空间前缀时,您将收到该错误。如果它没有在样式表中进一步声明(通常在文档元素上,如下所示:
),或者如果您选择了不同的命名空间前缀(例如将其声明为“xslt”,如下所示:xmlns:xslt="http: //www.w3.org/1999/XSL/Transform"
),那么当您尝试引用“xsl”时,它不会知道您指的是什么。您可以在
if
语句上声明xsl
命名空间前缀作为快速测试:您可以简化测试条件以选择
xsl:template
元素,而不是评估它们的count()
。如果选择了某些内容,test="//xsl:template"
的结果将评估为true()
,如果没有选择,则评估为false()
被选中。在样式表中,
xsl:template
是文档元素子元素的顶级构造。您可以使用更高效的 XPATH 表达式,而不是使用//
递归遍历 XML 文档树中的每个节点:Double check how you have declared the
xsl
namespace and what namespace-prefix you have chosen.You need to ensure that the
xsl
namespace prefix is defined in your stylesheet if you want to use it in your XPATH expressions. You will get that error when you try to use a namespace prefix that has not been declared.If it isn't declared anywhere further up in the stylesheet(typically on the document element like this:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
), or if you have chosen a different namespace prefix (e.g. declared it as "xslt" like this:xmlns:xslt="http://www.w3.org/1999/XSL/Transform"
), then when you attempt to reference "xsl" it won't know what you are referring to.You can declare the
xsl
namespace prefix on yourif
statement as a quick test:You can simplify your test condition to select the
xsl:template
elements, rather than evaluating thecount()
of them. The results oftest="//xsl:template"
will evaluate astrue()
if something is selected, andfalse()
if nothing is selected.In stylesheets
xsl:template
are top level constructs that are children of the document element. Rather than using//
to recurse through every node in the XML document tree, you can use a more efficient XPATH expression:假设 XSLT 代码文件始终包含
指令是不正确的。有一些 XSLT 样式表模块的示例,其中文件仅包含一条
指令和一个或多个全局级变量。这种样式表模块通常使用
或
指令导入/包含在另一个样式表模块中。此外,定义 XSLT 的并不是构成 XSLT 指令的元素的前缀。此前缀不强制为
"xsl"
,有些程序员使用不同的前缀,例如"xslt"
或"x"
。真正定义 XSLT 代码的是 XSLT 命名空间。
最后,XSLT 代码文件甚至不能保证包含
指令,因为 XSLT 提供了一个同义词:;
。考虑到所有这些考虑因素,更好的测试是:
因为存在 嵌入样式表,上面的测试可以稍微修改以涵盖这些:
It is incorrect to assume that an XSLT code file always contains an
<xsl:template>
instruction.There are examples of XSLT stylesheet modules where the file contains just an
<xsl:stylesheet>
instruction and one or more global-level variables. Such stylesheet module is typically imported/included in another stylesheet module using an<xsl:import>
or<xsl:include>
instruction.Also, what defines XSLT is not the prefix of the elements that constitute XSLT instructions. This prefix is not mandated to be
"xsl"
and some programmers use different prefixes, such as"xslt"
or"x"
.What really defines XSLT code is the XSLT namespace.
Finally, an XSLT code file isn't guaranteed even to contain an
<xsl:stylesheet>
directive, because XSLT offers a synonym:<xsl:transform>
.Taking in account all these considerations, a better test would be:
Because there exists the possibility of having embedded stylesheets, the test above can be slightly modified to cover these as well: