为什么我不必为XSLT中的节点属性指定命名空间?
举个例子,假设我有一个如下所示的XML:
<?xml version="1.0"?>
<timeline xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:xmlsn:axpz_namespace">
<A>
<B>
<C key="in"> bval <\C>
<C ind="ra"> bra <\C>
</B>
<\A>
我的xsl文件标题如下:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mms="urn:xmlsn:axpz_namespace">
C属性的select语句类似于:
select="./mms:B/mms:C[@key='in']"/>
select="./mms:B/mms:C[@ind='ra']"/>
但似乎您必须指定B
和C
是mms命名空间的一部分,那么您必须指定key
和ind
是也是该命名空间的一部分。即。
select="./mms:B/mms:C[@mms:key='in']"/>
select="./mms:B/mms:C[@mms:ind='ra']"/>
虽然很明显,如果您将节点名称空间指定为mms
,那么它的属性也应该在那里,如果您指定B
,那么看起来很明显在mms
命名空间内,C
也应该在那里。
这可能是一个微不足道的问题,可能只是依赖于正在使用的XSL阅读器,但我问,因为它让我很好奇你是否可以在各个节点上混合命名空间。例如,像:
select="./mms:B/othernamespace:C[@mms:key='in']"/>
我正在使用Saxon8B阅读器,我猜这种语法可能取决于我使用的阅读器。
答案 0 :(得分:5)
虽然xmlns=...
设置了元素的默认命名空间,但它没有为属性设置一个 - 您只在属性名称中获得一个命名空间如果你明确指定它。
它不应该依赖于您使用的XML API。
6.2命名空间默认
默认命名空间声明的范围从它出现的start-tag的开头延伸到相应的end-tag的末尾,不包括任何内部默认命名空间声明的范围。对于空标记,范围是标记本身。
默认名称空间声明适用于其范围内的所有未加前缀的元素名称。 默认命名空间声明不直接应用于属性名称;对无前缀属性的解释由它们出现的元素决定。
(强调我的。)
请注意,这不是关于XSLT或XPath的 - 它是关于纯XML和XML命名空间的。
答案 1 :(得分:2)
未加固定的属性始终位于“无名称空间”。
Jon Skeet的回答是这样的:
“因为W3C命名空间规范是这么说的”
让我解释一下这样一个设计决定背后的原因:
逻辑是属性完全由它出现的元素定义,因此如果元素属于特定的命名空间,则不需要指定它们的任何属性属于该(或其他)命名空间。
换句话说,属性不需要命名空间来消除歧义,就像元素的情况一样 - 因为属性完全被它所属的元素消除歧义。
因此,在设计新的基于XML的词汇表时,将属性定义为属于命名空间是个坏主意。
此常识规则的一个例外是具有全局范围的属性(可以出现在任何元素上)。此类属性的示例包括:xml:lang
,xml:space
,...等