动态创建的XML上的getElementById


getElementById on dynamically created XML

这个例子不言自明,我希望getElementById返回第二个元素,但给出了NULL。为什么?

$dom = new DOMDocument();
$root = $dom->createElement("root");
$el = $dom->createElement("element");
$el->setAttribute("id", "1");
$root->appendChild($el);
$el = $dom->createElement("element");
$el->setAttribute("id", "2");
$root->appendChild($el);
$dom->appendChild($root);
// OK
echo $dom->saveXML();
// NOT OK
var_dump($dom->getElementById("2"));

使用XML,getElementById方法返回元素,对于这些元素,DTD中已将某个属性定义为具有类型ID,而不是名为id的元素。因此,如果您想使用这种方法,您需要确保有一个DTD为名为element的元素和名为id的属性声明类型ID

$dom = new DOMDocument();
$dom->loadXML("<!DOCTYPE root [<!ATTLIST element id ID #IMPLIED>]><root/>");
$root = $dom->documentElement;

似乎在PHP DOM API中做

$el = $dom->createElement("element");
$el->setAttribute("id", "2");
$el->setIdAttribute("id", TRUE);

用作具有DTD的替代方案。

id仅是由DTD/XSD或API定义的id属性。XML中唯一预定义的id属性是xml:id{http://www.w3.org/XML/1998/namespace}id)。

您可以使用Xpath根据节点的属性值获取节点。它不需要通过id属性:

$xml = <<<'XML'
<?xml version="1.0"?>
<root>
  <element id="1"/>
  <element id="2"/>
  <element id="3"/>
</root>
XML;
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
var_dump(
  $xpath->evaluate('//*[@id=2]')->item(0)->getAttribute('id')
);

输出:

string(1) "2"