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

时间:2012-11-02 21:19:37

标签: 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>

我的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']"/>

但似乎您必须指定BC是mms命名空间的一部分,那么您必须指定keyind是也是该命名空间的一部分。即。

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阅读器,我猜这种语法可能取决于我使用的阅读器。

2 个答案:

答案 0 :(得分:5)

虽然xmlns=...设置了元素的默认命名空间,但它没有为属性设置一个 - 您只在属性名称中获得一个命名空间如果你明确指定它。

它不应该依赖于您使用的XML API。

来自"Namespaces in XML 1.0"

  

6.2命名空间默认

     

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

     

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

(强调我的。)

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

答案 1 :(得分:2)

未加固定的属性始终位于“无名称空间”。

Jon Skeet的回答是这样的:

  

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

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

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

换句话说,属性不需要命名空间来消除歧义,就像元素的情况一样 - 因为属性完全被它所属的元素消除歧义。

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

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