PHP Conference Japan 2024

DOMDocument::getElementById

(PHP 5, PHP 7, PHP 8)

DOMDocument::getElementById搜索具有特定 ID 的元素

描述

public DOMDocument::getElementById(string $elementId): ?DOMElement

此函数类似于 DOMDocument::getElementsByTagName,但搜索具有给定 ID 的元素。

要使此函数正常工作,您需要使用 DOMElement::setIdAttribute 设置一些 ID 属性,或者使用定义属性为 ID 类型的 DTD。在后一种情况下,您需要使用 DOMDocument::validateDOMDocument::$validateOnParse 验证您的文档,然后才能使用此函数。

参数

elementId

元素的唯一 ID 值。

返回值

返回 DOMElementnull(如果未找到元素)。

示例

示例 #1 DOMDocument::getElementById() 示例

以下示例使用 book.xml,其中包含以下内容

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE books [
  <!ELEMENT books   (book+)>
  <!ELEMENT book    (title, author+, xhtml:blurb?)>
  <!ELEMENT title   (#PCDATA)>
  <!ELEMENT blurb   (#PCDATA)>
  <!ELEMENT author  (#PCDATA)>
  <!ATTLIST books   xmlns        CDATA  #IMPLIED>
  <!ATTLIST books   xmlns:xhtml  CDATA  #IMPLIED>
  <!ATTLIST book    id           ID     #IMPLIED>
  <!ATTLIST author  email        CDATA  #IMPLIED>
]>
<?xml-stylesheet type="text/xsl" href="style.xsl"?>
<books xmlns="http://books.php/" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <book id="php-basics">
    <title>PHP Basics</title>
    <author email="[email protected]">Jim Smith</author>
    <author email="[email protected]">Jane Smith</author>
    <xhtml:blurb><![CDATA[
<p><em>PHP Basics</em> provides an introduction to PHP.</p>
]]></xhtml:blurb>
  </book>
  <book id="php-advanced">
    <title>PHP Advanced Programming</title>
    <author email="[email protected]">Jon Doe</author>
  </book>
</books>
<?php

$doc
= new DomDocument;

// 我们需要在引用 ID 之前验证我们的文档
$doc->validateOnParse = true;
$doc->Load('book.xml');

echo
"The element whose id is 'php-basics' is: " . $doc->getElementById('php-basics')->tagName . "\n";

?>

以上示例将输出

The element whose id is 'php-basics' is: book

参见

添加注释

用户贡献的注释 10 条注释

ed at edgiardina dot com
14 年前
请注意,如果您的 HTML 不包含文档类型声明,则 getElementById 将始终返回 null。
carl2088 at gmail dot com
15 年前
根据我的经验,如果您加载了 HTML 文档,则 getElementById 似乎可以正常工作,无需任何设置。但是,为了使 getElementById 与您“构建”的简单 XML 文档一起使用,您必须使用“xml:”前缀设置 ID,并在您创建的元素上使用 setIdAttribute,否则它将无法工作。请参阅以下示例,希望这可以节省一些人的挫败感。如果您加载了 xml 文件,那么您只需确保 ID 具有 xml: 属性前缀即可。但是,如果您开始追加 XML 文档,请不要忘记在 id 名称或这些元素上使用 setIdAttribute,否则当您尝试查找它们时,getElementById 将返回 null。



<?php

/* test.xml
<?xml version="1.0" encoding="utf-8"?>
<root>
<child xml:id="id_xxxxxx" status="partial">
<sub_child>Some Data</sub_child>
</child>
</root>
*/

$xmlDom = new DOMDocument('1.0', 'utf-8');
$xmlDom->formatOutput = true; // 我们希望得到一个格式良好的输出

// 创建根节点
$eltRoot = $xmlDom->createElement("root");
$xmlDom->appendChild($eltRoot);

$eltChild = $xmlDom->createElement("child");
$eltRoot->appendChild($eltChild);

// 添加一个 id 属性
$attr = $xmlDom->createAttribute("xml:id"); // 需要 xml 前缀,否则 getElementById 无法工作
$eltChild->appendChild($attr);

/// 创建文本节点并追加到创建的元素
$tNode = $xmlDom->createTextNode("id_8120528");
$attr->appendChild($tNode);
$eltChild->setIdAttribute("xml:id", true); // 非常重要,否则 getElementById 无法工作

// 添加一个 id 属性
$attr = $xmlDom->createAttribute("status");
$eltChild->appendChild($attr);

/// 创建文本节点并追加到创建的元素
$tNode = $xmlDom->createTextNode("partial");
$attr->appendChild($tNode);

// 添加一个子节点
$eltSub = $xmlDom->createElement("sub_child");
$eltChild->appendChild($eltSub);

$tNode = $xmlDom->createTextNode("Some Data");
$eltSub->appendChild($tNode);

$id = null;
$id = $xmlDom->getElementById("id_8120528");

assert ($id != null);

$strId = $id->getAttribute("xml:id"); // bug?为空
$strStatus = $id->getAttribute("status"); // 这段代码可以工作!

assert ($id !=null);

$xmlDom->save("./_data/test.xml");

$xmlDom->load("./_data/test.xml"); // 重新加载修复了问题

$nodeRoot = $xmlDom->getElementsByTagName("root");
if (
$nodeRoot->length > 0) {
$eltRoot = $nodeRoot->item(0);
}

assert($eltRoot != null);

$id = null;
$id = $xmlDom->getElementById("id_8120528");

assert ($id != null);

$strId = $id->getAttribute("xml:id"); // 现在可以工作了!
$strStatus = $id->getAttribute("status"); // 这段代码可以工作!


?>
paradox_haze at live dot de
14 年前
在 XHTML 文档中搜索特定元素时,遇到了一些 getElementById() 的问题。
我编写了一个小函数来解决我的问题。

<?php
function getElementById($id)
{
$xpath = new DOMXPath($this->domDocument);
return
$xpath->query("//*[@id='$id']")->item(0);
}
?>
simon at somewhere dot com
17 年前
避免让自己陷入巨大的头痛和大量搜索文档的境地 -

不要使用 $object->setAttribute('id', 'id_name_here')
使用这个:$object->setAttribute('xml:id', 'id_name_here')

然后,获取节点值:$domDocumentObject->getElementById('id_name_here');

xml:id 属性应该自动定义!

太棒了!这很容易……
bart at mediawave dot nl
19 年前
getElementById 似乎在不将 validateOnParse 设置为 true 的情况下也能正常工作。这很好,因为将其设置为 true 会导致我的脚本出现一些性能问题。
匿名用户
18 年前
如果您尝试对已根据 xsd 文件验证的 xml 文件使用 getElementById,则必须首先使用 schemaValidate 函数,否则 getElementById 将返回 null。
示例

$dom = new DomDocument();
$dom->load("users.xml");
$dom->schemaValidate("users.xsd");

$curruser = $dom->getElementById($user->name);
Hoi
4 年前
要设置一个 $dom->getElementById() 可以使用的隐藏 id,请像以下示例中那样应用 setAttribute('id', true)

$createItemNode = function ($data) use ($dom) {
$node = $dom->createElement("Item");
$node->setAttribute('id', $data->id);
$node->setAttribute('hed', $data->hed);
$node->setAttribute('run_time', $data->run_time);
$node->setAttribute('date', $data->date);

// 在内部将 id 标记为 'xml:id' 以使 getElementById 工作。手动将 xml:id 添加到标签会导致 loadXML 抛出错误 DOMDocument:xml:id 不是实体中的 NCName
$node->setIdAttribute('id', true);

return $node;
};

使用 $node->setIdAttribute('id', true),$dom->getElementById($id) 将可以工作。

当您执行 $dom->saveXML() 时,最终文档将不包含任何 xml:id 属性。
Tangui dot Le-Pense at laposte dot net
18 年前
有时无法从 DTD 验证文档以使用 getElementById(例如,当 XHtml 文档中尚未包含 head 和 body 元素时:验证失败)。
幸运的是,此函数支持 xml:id :)
这可能很有用。
http://www.w3.org/TR/xml-id/
jonbarnett at gmail dot com
18 年前
如果您的 XML 文档没有定义“id”属性为 ID 的 DTD,那么最简单的方法是使用 XPath->query() 查找与“//[@id='x']”匹配的元素。
guillaume dot crico at gmail dot com
16 年前
您不想使用“xml:id”吗?
这是 relaxNG 技巧(使用通用模式)
(已使用 libxml 2.6.26 测试)

<?php
$doc
= new DOMDocument();
$doc->load(...);

$rng = '
<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<start>
<element>
<anyName/>
<ref name="anythingID"/>
</element>
</start>
<define name="anythingID">
<zeroOrMore>
<choice>
<element>
<anyName/>
<ref name="anythingID"/>
</element>
<attribute name="id">
<data type="ID"/>
</attribute>
<zeroOrMore>
<attribute><anyName/></attribute>
</zeroOrMore>
<text/>
</choice>
</zeroOrMore>
</define>
</grammar>
'
;

$doc->relaxNGValidateSource($rng);
var_dump($doc->getElementById('id1'));
?>


请注意,ID 值必须是有效的
- 整数不起作用!
- @see http://www.w3.org/TR/REC-xml/#id
- => (字母 | '_' | ':') ( 字母 | 数字 | '.' | '-' | '_' | ':' | 组合字符 | 扩展字符 )*
To Top