我在Saxon的XSLT处理器(最新版本=9.?)上遇到了这个奇怪的问题
给定这个伪造的XML(不管是什么):
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="urn:bogus">bogus</root>
使用此XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<x:transform version="2.0"
xmlns:x="http://www.w3.org/1999/XSL/Transform"
xmlns:b="urn:bogus"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:foobar"
xpath-default-namespace="urn:foobar"
exclude-result-prefixes="#all">
<x:output method="xml" indent="yes" encoding="UTF-8" />
<x:template match="b:root">
<foo xsi:type="xs:string"><x:value-of select="."/></foo>
</x:template>
</x:transform>
将实际删除xmlns:xs="http://www.w3.org/2001/XMLSchema"由于排除结果前缀="#all",结果XML中的声明。显然,发生这种情况是因为它用于属性值,而不是元素或属性。
删除排除结果前缀="#all"或手动指定要删除的前缀确实有效。
这是故意的行为吗?我猜处理器将所有属性值视为随机字符串,并且不考虑它们的名称空间(它甚至没有注意到它有一个名称空间)。
对于像xsi:type这样的众所周知的属性,应该有特殊的行为吗?
我看不出来http://www.w3.org/TR/xslt20/#namespace-fixup要求处理器检查类型名称的属性值,正如它所说:
命名空间修复程序不用于为创建命名空间声明出现在元素内容中的xs:QName或xs:NOTATION值或属性。
在值获取验证结果、命名空间等类型的情况下修复不起作用,因为名称空间修复以前发生过验证:在这种情况下,用户有责任确保要验证的元素具有所需的命名空间节点,以使验证成功。
基于此,我认为样式表作者有责任确保xs
前缀绑定到URI http://www.w3.org/2001/XMLSchema
。