如果您只想让 ID 机制工作,最简单的选择是使用xml:id
:
<root xml:id="root">
<p xml:id="p1"><i>Title</i></p>
<p xml:id="p2"><b xml:id="b1">AAA<sup>1</sup>, BBB<sup>2</sup></b></p>
</root>
根据https://fosswiki.liip.ch/display/BLOG/GetElementById+Pitfalls,xml:id
应该可以getElementById
在 PHP 中使用。
您尝试的问题:
后面的元素名称<!DOCTYPE
必须与 XML 文档的根元素的名称相匹配。在您的情况下,noname
!=root
不起作用。请参阅http://www.w3.org/TR/xml/#sec-prolog-dtd。
必须为每个元素声明属性。您不能为 声明属性ANY
。而且即使一个元素的内容模型是ANY
,你仍然必须声明所有可能出现的元素。
所以没有办法为ID解析创建一个DTD。以下验证,它不能真正小于这个:
<!DOCTYPE root [
<!ELEMENT root (p+)>
<!ATTLIST root
id ID #IMPLIED>
<!ELEMENT p ANY>
<!ATTLIST p
id ID #IMPLIED>
<!ELEMENT b ANY>
<!ATTLIST b
id ID #IMPLIED>
<!ELEMENT sup (#PCDATA)>
<!ELEMENT i (#PCDATA)>
]>
<root id="root">
<p id="p1"><i>Title</i></p>
<p id="p2"><b id="b1">AAA<sup>1</sup>, BBB<sup>2</sup></b></p>
</root>
只要 XML 解析器不尝试验证,就可以提供更小的 DTD。xmllint(和 PHP)以非验证模式接受此文档:
<!DOCTYPE anyname [
<!ATTLIST p id ID #IMPLIED>
]>
<root id="root">
<p id="p1"><i>Title</i></p>
<p id="p2"><b id="b1">AAA<sup>1</sup>, BBB<sup id="b1">2</sup></b></p>
</root>
p
并报告元素的ID 唯一性违规。
如果 xmllint 使用该--postvalid
选项运行(或 PHP 在LIBXML_DTDVALID
启用的情况下运行),则会发出:
test.xml:4: element root: validity error : root and DTD name do not match 'root' and 'anyname'