为什么XSLT中的属性不需要名称空间声明

sma*_*oun 5 xml xslt xpath

为什么我不必在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>
Run Code Online (Sandbox Code Playgroud)

和我的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">
Run Code Online (Sandbox Code Playgroud)

C属性的select语句如下所示:

select="./mms:B/mms:C[@key='in']"/>
select="./mms:B/mms:C[@ind='ra']"/>
Run Code Online (Sandbox Code Playgroud)

但似乎你必须指定它B并且C是mms命名空间的一部分,那么你应该指定它key并且ind也是该命名空间的一部分.即

select="./mms:B/mms:C[@mms:key='in']"/>
select="./mms:B/mms:C[@mms:ind='ra']"/>
Run Code Online (Sandbox Code Playgroud)

虽然很明显,如果你要指定节点名称空间,mms那么它的属性也应该在那里,看起来很明显,如果你指定Bmms命名空间内,那么也C应该在那里.

这可能是一个微不足道的问题,可能只是依赖于正在使用的XSL阅读器,但我问,因为它让我很好奇你是否可以在各个节点上混合名称空间.例如,类似于:

select="./mms:B/othernamespace:C[@mms:key='in']"/>
Run Code Online (Sandbox Code Playgroud)

我正在使用Saxon8B阅读器,我猜这种语法可能取决于我使用的阅读器.

Jon*_*eet 5

尽管xmlns=...元素设置了默认命名空间,但它没有为属性设置一个- 如果明确指定属性,则只能在属性名称中获取命名空间.

它不应该取决于您使用的XML API.

"XML 1.0中的命名空间":

6.2命名空间默认

默认命名空间声明的范围从它出现的start-tag的开头延伸到相应的end-tag的末尾,不包括任何内部默认命名空间声明的范围.对于空标记,范围是标记本身.

默认名称空间声明适用于其范围内的所有未加前缀的元素名称.默认名称空间声明不直接应用于属性名称 ; 对无前缀属性的解释由它们出现的元素决定.

(强调我的.)

请注意,这与XSLT或XPath无关 - 它是关于纯XML和XML命名空间的.


Dim*_*hev 1

无前缀的属性始终位于“无命名空间”中。

乔恩·斯基特的回答是这样的:

“因为 W3C 命名空间规范是这么说的”

让我解释一下这样的设计决策背后的原因

逻辑是属性完全由它出现的元素定义,因此如果元素属于特定的命名空间,则无需指定它们的任何属性属于该(或其他)命名空间。

换句话说,属性不需要像元素那样通过命名空间来消除歧义——因为属性完全由它所属的元素消除歧义。

因此,在设计新的基于 XML 的词汇表时,将属性定义为属于名称空间是一个坏主意。

此常识性规则的一个例外是具有全局范围的属性(可以出现在任何元素上)。此类属性的示例有:xml:langxml:space、 ... 等。