我正在尝试使用apache fop格式化PDF报告,我发现了一种我无法理解的行为。
在尝试调试问题时,我将其跟踪到xsl:template match指令的xsl行为,在xml文件中声明和不声明名称空间。
即使我使用另一个implmentation(xsltproc),xsl的行为也是一样的,所以差异应该在xsl规范中,它与apache fop无关,但是我无法找到解释,所以我会如果有人可以帮助我,我会非常感激。
这是代码。首先是“bugger.xml”文件:
<?xml version="1.0" encoding="UTF-8" ?>
<parent xmlns="http://www.bugger.org">parent_value</parent>
这是“bugger.xsl”文件:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="/">
OK, root element matches...
<xsl:apply-templates />
</xsl:template>
<xsl:template match="/*">
you WILL see this writing... I'm a parent tag, look: I'm a "<xsl:value-of select="name()"/>", why you cannot see me in the /parent template match?
The naming match fails because of the xmlns directive in the bugger.xml file. If you remove it, all works fine.
</xsl:template>
<xsl:template match="/parent">
you will NOT see this writing, while you should see it...
</xsl:template>
</xsl:stylesheet>
问题是:为什么如果我放置xmlns =“http://www.bugger.org”指令,xsl:template匹配“/ *”,如果我删除它,xsl:template匹配“ / parent“?
感谢您的帮助!!!
答案 0 :(得分:1)
当你的来源是:
<?xml version="1.0" encoding="UTF-8" ?>
<parent xmlns="http://www.bugger.org">parent_value</parent>
这个模板:
<xsl:template match="/parent">
you will NOT see this writing, while you should see it...
</xsl:template>
与源XML文件中的任何内容都不匹配,也不会应用。 OTOH,这个模板:
<xsl:template match="/*">
you WILL see this writing... I'm a parent tag, look: I'm a "<xsl:value-of select="name()"/>", why you cannot see me in the /parent template match?
The naming match fails because of the xmlns directive in the bugger.xml file. If you remove it, all works fine.
</xsl:template>
与根元素匹配(在此示例中本地名称为parent
),因此将应用于该元素。
现在,当你的来源是:
<?xml version="1.0" encoding="UTF-8" ?>
<parent>parent_value</parent>
然后两个模板都匹配根parent
元素 - 并且具有相同的优先级(0.5)。在这种情况下,处理器将选择最后一个匹配模板 - 请参阅:https://www.w3.org/TR/xslt/#conflict
注意强>:
/
是根节点,而不是根元素。
&#34; xmlns =&#34; http://www.bugger.org"指令&#34;被称为名称空间声明 - 建议您更多地了解XML中的名称空间以及如何在XSLT中处理它们。
答案 1 :(得分:1)
使用:
"Uncaught SyntaxError: Unexpected token :"
您已将“默认命名空间”设置为“http://www.bugger.org”命名空间URI。见https://www.w3.org/TR/REC-xml-names/#defaulting
XSLT处理器(以及实现处理XML的REC-xml名称的任何其他内容)将'parent'元素视为'in'(非技术术语)'http://www.bugger.org'命名空间。< / p>
在样式表中,<parent xmlns="http://www.bugger.org">parent_value</parent>
匹配,因为/*
(在此上下文中)匹配所有元素。 *
不匹配,因为它只匹配带有空名称空间URI的/parent
(这就是删除名称空间声明时匹配的原因)。见https://www.w3.org/TR/xpath/#node-tests
(另外,在您展示的样式表中,您不需要匹配模式中的前导parent
。)
要在/
上专门匹配“http://www.bugger.org”命名空间URI,您需要匹配元素的“限定名称”(QName)。即,您需要在匹配模式中使用带有parent
的名称空间前缀,即使您可以使用与源XML中的默认名称空间相同的名称空间URI(因为在XSLT中,模式中的非限定名称始终位于null namespace):
parent