冒号是 XML 标记名称中合法的第一个字符吗?

Eli*_*ott 3 xml specifications colon well-formed

根据W3C XML Recommendation,开始标记名称具有定义:

STag ::= '<' Name (S Attribute)* S? '>'
Run Code Online (Sandbox Code Playgroud)

..哪里Name是:

Name ::= NameStartChar (NameChar)*
NameStartChar ::= ":" | [A-Z] | ...
Run Code Online (Sandbox Code Playgroud)

..(注意,说明冒号可以作为第一个字符出现)表明以下是一个有效的 XML 文档:

<?xml version="1.0" ?><:doc></:doc>
Run Code Online (Sandbox Code Playgroud)

..但是我尝试的任何解析器都将冒号显示为格式错误。

此外,在附录 B(虽然现在是文档的折旧部分)下,它明确指出:

Characters ':' and '_' are allowed as name-start characters.
Run Code Online (Sandbox Code Playgroud)

..和:

<?xml version="1.0" ?><_doc></_doc>
Run Code Online (Sandbox Code Playgroud)

.. 被我尝试过的 XML 解析器所接受。

那么,冒号是标签名中的第一个有效字符吗,我使用的解析器是错误的,还是我读错了规范?

kjh*_*hes 5

是的,在基本 XML 级别,:允许冒号 ( ) 作为名称开始字符。您引用的 BNF 规则明确指出了这一点。

但是,W3C XML 建议明确指出,除了命名空间目的外,不应使用冒号:

笔记:

XML 建议中的命名空间[XML 名称]为包含冒号字符的名称分配了含义。因此,作者不应在 XML 名称中使用冒号,除非是出于命名空间的目的,但 XML 处理器必须接受冒号作为名称字符。

并且标记的XML 命名空间BNF 规则基于QName,它允许名称中的冒号仅作为Prefix和之间的分隔符LocalPart

QName          ::= PrefixedName | UnprefixedName
PrefixedName   ::= Prefix ':' LocalPart
UnprefixedName ::= LocalPart
Prefix         ::= NCName
LocalPart      ::= NCName
NCName         ::= Name - (Char* ':' Char*) /* An XML Name, minus the ":" */
Run Code Online (Sandbox Code Playgroud)

有人可能会问为什么NameStartChar从一开始就不允许冒号。如果幸运的话,CM Sperberg-McQueen 可能会提供权威的解释。但是,我怀疑这是一个关于如何设计命名空间的不断发展的概念的问题。

在1996年首次出版工作草案的W3C XML建议中有一个定义STag,其并没有让冒号

STag  ::= '<' Name (S Attribute)* S? '>'
Name  ::= (Letter | '-') (Letter | Digit | '-' | '.')*
Run Code Online (Sandbox Code Playgroud)

到 1998 年,冒号被允许在Name

Name  ::= (Letter | '_' | ':') (NameChar)*
Run Code Online (Sandbox Code Playgroud)

关于冒号使用的警告的早期形式如下:

注意: XML 名称中的冒号字符保留用于名称空间的实验。它的含义预计将在未来某个时候标准化,届时可能需要更新那些出于实验目的使用冒号的文档。(不能保证任何用于 XML 的命名空间机制实际上都会使用冒号作为命名空间分隔符。)实际上,这意味着作者不应在 XML 名称中使用冒号,除非作为命名空间的一部分实验,但 XML 处理器应该接受冒号作为名称字符。

需求是预料之中的,但是当冒号第一次被引入标记名称时,确切的形式可能还不知道。