2

我有这个简单的 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 规范指定如果元素与一组条件中的一个匹配,则该元素是有效的,其中一个条件是:

声明与 Mixed 匹配,并且内容(在将任何实体引用替换为其替换文本之后)由字符数据(包括 CDATA 部分)、注释、PI 和其类型与内容模型中的名称匹配的子元素组成。

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

混合的产生是:

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

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

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

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

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

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

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

严格遵守具有 content 的元素的有效性要求(#PCDATA)

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

规范似乎只要求子元素的名称与 DTD 中元素的名称相匹配,但我认为这些元素的内容和属性也应该与 DTD 中的声明相匹配,但规范实际上并没有这么说。因此,再次严格遵守规范的有效性要求,具有内容的元素的子元素的内容和属性是否必须与(#PCDATA)DTD 中的这些声明相匹配?如果是这样,规范中的哪里是这样说的?

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

4

1 回答 1

1

你的元素声明,

<!ELEMENT input (#PCDATA)>

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

您引用的部分说混合内容 可能包含字符数据,可选地穿插子元素。 该部分的生产支持这一点。见^^^下文,如果由 提供,则允许混合元素Name

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

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

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

更新以解决后续评论

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

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


1同样,请注意规范说optional interspersed。这是完整的定义:

3.2.2 混合内容

[定义:当该类型的元素可能包含字符数据时, 该元素类型具有混合内容,可选地穿插有元素。]

于 2020-10-16T03:08:56.410 回答