5

为什么我不必为 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也是该命名空间的一部分。IE

select="./mms:B/mms:C[@mms:key='in']"/>
select="./mms:B/mms:C[@mms:ind='ra']"/>

虽然很明显,如果您指定要在其中的节点命名空间,mms那么它的属性也应该在其中,但如果您指定在命名空间内,那么它似乎也B应该mmsC其中。

这可能是一个微不足道的问题,并且可能仅取决于所使用的 XSL 阅读器,但我之所以这么问,是因为它让我很好奇您是否可以在各种节点上混合命名空间。例如,类似:

select="./mms:B/othernamespace:C[@mms:key='in']"/>

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

4

2 回答 2

4

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

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

来自“XML 1.0 中的命名空间”

6.2 命名空间默认

默认命名空间声明的范围从它出现的开始标签的开头延伸到相应的结束标签的末尾,不包括任何内部默认命名空间声明的范围。在空标签的情况下,范围是标签本身。

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

(强调我的。)

请注意,这实际上与 XSLT 或 XPath 无关——它与纯 XML 和 XML 名称空间有关。

于 2012-11-02T21:21:12.450 回答
1

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

Jon Skeet 的回答是这样的:

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

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

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

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

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

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

于 2012-11-03T03:52:42.107 回答