#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>

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

如果我删除了input元素内的file元素,那么报告的结果XML是有效的,因此我希望“非文本节点”是子元素(输入中的文件以及名称和类型的文件)。 / p>

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

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

请注意结尾处的“和子元素...”。

混合生产为:

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

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

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

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

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

但是,即使在DTD中没有声明文件名称和类型元素,也有其他验证器报告XML是有效的。这也似乎是验证者的错,因为验证要求明确指出,子元素名称必须与内容模型中的名称匹配,而在删除那些元素声明时,子元素名称必须与内容模型中的名称不匹配。

我知道有各种各样的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)*>

更新以处理后续评论

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

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


1 再次注意,规范指出可选地穿插。这是完整的定义:

3.2.2 Mixed Content

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...