XML #PCDATA 验证

XML validation of #PCDATA

我有这个简单的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE input[
<!ELEMENT input (#PCDATA)>
<!ELEMENT file (#PCDATA)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT type (#PCDATA)>
]>
<input>
This is the content <file><name>test.png</name><type>Image</type></file>
</input>

我希望这是有效的,但一些在线验证器报告它无效,因为输入和文件元素包含非文本节点。

如果我删除输入元素中的文件元素,则结果 XML 被报告为有效,因此我希望“非文本节点”是子元素(输入中的文件和名称以及输入文件)。

我希望这是有效的,因为 XML specification for an element 指定如果元素符合一组条件之一,则元素有效,其中一个是:

The declaration matches Mixed, and the content (after replacing any entity references with their replacement text) consists of character data (including CDATA sections), comments, PIs and child elements whose types match names in the content model.

注意最后的“和子元素...”。

混合的产量是:

    Mixed      ::=      '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*'  
            | '(' S? '#PCDATA' S? ')' 

第二种情况是我的输入和文件:(#PCDATA)

混合内容的有效性要求是可以有子元素,只要它们的名称与内容模型中的名称匹配即可。

是我误解了规范还是这些验证器不正确?

如果我从 DTD 中删除文件、名称和类型元素的声明,但将子元素保留在输入元素的内容中,那么我会收到额外的验证错误,表明没有这些类型的声明。我预计会出现这些错误,因为验证要求是子元素名称与内容模型中的名称匹配,并且在删除这些声明后,它们与内容模型中的名称不匹配。

但是还有其他验证器报告 XML 即使没有 DTD 中文件、名称和类型元素的声明也是有效的。这似乎也是验证器的错误,因为验证要求清楚地表明子元素名称必须与内容模型中的名称匹配,而当这些元素声明被删除时,它们不会匹配。

我知道有多种 XML 验证实现,它们的工作方式不尽相同,因此它们不可能都严格正确。我最感兴趣的是严格正确地理解规范。

严格遵守内容(#PCDATA):

元素的有效性要求
  1. 该元素的内容可以包含子元素吗?
  2. 如果是,这些元素的名称必须与 DTD 中的元素名称匹配吗?

规范似乎只要求子元素的名称与 DTD 中的元素名称相匹配,但我认为合理的是,此类元素的内容和属性也应与 DTD 中的声明相匹配,但规范并未其实这样说。那么,再次严格遵守规范的有效性要求,内容为 (#PCDATA) 的元素的子元素的内容和属性是否必须与 DTD 中的声明相匹配?如果是这样,规范中的什么地方是这样说的?

最后,是否有任何易于使用(在线或可安装到 Linux)XML 严格按照规范正确的验证器,您可以推荐吗?

你的元素声明,

<!ELEMENT input (#PCDATA)>

技术上允许混合内容,但不允许混入任何元素。

您引用的 section 表示混合内容 可能包含字符数据,可选地散布在子元素中。 该部分的制作支持这一点。请参阅下面的 ^^^,如果 Name:

提供,则允许混合元素
Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*'  
                           ^^^^^^^^^^^^^^^^^       
        | '(' S? '#PCDATA' S? ')' 

但是,您的声明实际上不允许元素。如果您希望允许混入 file 等元素,请改为像这样声明 input

<!ELEMENT input (#PCDATA|file)*>

更新地址 follow-up 评论

出现在已解析字符数据中的任何&<字符将被解析:即,解释为标记。 well-formedness 的规则适用,并且在验证期间,解析的标记必须遵循模式给出的语法规则。内容模型中只有 #PCDATA 的元素不会隐式允许散布在内容模型中未提及的元素。

通俗地说,混合内容 通常意味着存在散布的元素;从技术上讲,混合内容可能有零个或多个元素1。无论哪种方式,如果元素散布在已解析的数据中但未在内容模型中指定,则文档无效。


1 同样,请注意规范说 可选地穿插 。这是完整的定义:

3.2.2 Mixed Content

[Definition: An element type has mixed content when elements of that type may contain character data, optionally interspersed with child elements.]