justinpatrin at php dot net
> 要获得一个正确的 DOM 文档(大多数操作都需要),您需要...
您不需要。只需执行以下操作
<?php
$dom = dom_import_simplexml($xml)->ownerDocument;
?>
(PHP 5、PHP 7、PHP 8)
dom_import_simplexml — 从 SimpleXMLElement 对象获取 DOMElement 对象
此函数获取给定的属性或元素 node
(一个 SimpleXMLElement 实例)并分别创建一个 DOMAttr 或 DOMElement 节点。新的 DOMNode 指向与 SimpleXMLElement 相同的底层 XML 节点。
版本 | 描述 |
---|---|
8.0.0 | 此函数在失败时不再返回 null 。 |
示例 #1 使用 dom_import_simplexml() 将 SimpleXML 导入 DOM
<?php
$sxe = simplexml_load_string('<books><book><title>blah</title></book></books>');
if ($sxe === false) {
echo '解析文档时出错';
exit;
}
$dom_sxe = dom_import_simplexml($sxe);
if (!$dom_sxe) {
echo '转换 XML 时出错';
exit;
}
$dom = new DOMDocument('1.0');
$dom_sxe = $dom->importNode($dom_sxe, true);
$dom_sxe = $dom->appendChild($dom_sxe);
echo $dom->saveXML();
?>
以上示例将输出
<?xml version="1.0"?> <books><book><title>blah</title></book></books>
示例 #2 将 SimpleXML 导入 DOM 并通过 DOM 修改 SimpleXML
为简洁起见,省略了错误处理。
<?php
$sxe = simplexml_load_string('<books><book><title>blah</title></book></books>');
$elt = dom_import_simplexml($sxe);
$elt->setAttribute("foo", "bar");
echo $sxe->asXML();
?>
以上示例将输出
<?xml version="1.0"?> <books foo="bar"><book><title>blah</title></book></books>
justinpatrin at php dot net
> 要获得一个正确的 DOM 文档(大多数操作都需要),您需要...
您不需要。只需执行以下操作
<?php
$dom = dom_import_simplexml($xml)->ownerDocument;
?>
//示例 #1 无需初始化、导入和追加
(...)
$dom_sxe = dom_import_simplexml($sxe);
if (!$dom_sxe) {
echo '转换 XML 时出错';
exit;
}
//$dom = new DOMDocument('1.0');
//$dom_sxe = $dom->importNode($dom_sxe, true);
//$dom_sxe = $dom->appendChild($dom_sxe);
//使用 ownerDocument 属性
echo $dom->ownerDocument->saveXML();
?>
SimpleXML 是一个“对象映射 XML API”。它本身不是 DOM。SimpleXML 将 XML 元素转换为 PHP 的原生数据类型。
dom_import_simplexml 和 simplexml_import_dom 函数 *不会* 创建原始对象的单独副本。您可以自由地交替使用任一或两个函数的方法,因为底层实例是相同的。
<?php
// 初始化一个 simplexml 对象
$sxe = simplexml_load_string('<root/>');
// 获取 simplexml 对象上的 dom 接口
$dom = dom_import_simplexml($sxe);
// dom 在根元素下添加一个新元素
$element = $dom->appendChild(new DOMElement('dom_element'));
// dom 在新元素上添加一个属性
$element->setAttribute('creator', 'dom');
// simplexml 在 dom 元素上添加一个属性
$sxe->dom_element['sxe_attribute'] = 'added by simplexml';
// simplexml 在根元素下添加一个新元素
$element = $sxe->addChild('sxe_element');
// simplexml 在新元素上添加一个属性
$element['creator'] = 'simplexml';
// dom 找到 simplexml 元素(通过 DOMNodeList->index)
$element = $dom->getElementsByTagName('sxe_element')->item(0);
// dom 在 simplexml 元素上添加一个属性
$element->setAttribute('dom_attribute', 'added by dom');
echo ('<pre>');
print_r($sxe);
echo ('</pre>');
?>
输出
SimpleXMLElement 对象
(
[dom_element] => SimpleXMLElement 对象
(
[@attributes] => 数组
(
[creator] => dom
[sxe_attribute] => 由 SimpleXML 添加
)
)
[sxe_element] => SimpleXMLElement 对象
(
[@attributes] => 数组
(
[creator] => simplexml
[dom_attribute] => 由 DOM 添加
)
)
)
这说明这两个接口都在操作同一个底层对象实例。此外,当您使用 dom_import_simplexml 时,您可以创建和添加新元素,而无需引用 ownerDocument(或 documentElement)。
因此,将 SimpleXMLElement 传递给另一个方法并不意味着接收方仅限于使用 SimpleXML 方法。
瞧!您的望远镜变成了双筒望远镜!
我发现较新的 PHP5 版本需要一些特殊的语法才能在 SimpleXML 和 DOM 之间正确转换。它不像使用 SimpleXML 节点调用 dom_import_simplexml() 那么简单。要获得一个正确的 DOM 文档(您需要执行大多数操作),您需要
<?php
//$xml 是一个 SimpleXML 实例
$domnode = dom_import_simplexml($xml);
$dom = new DOMDocument();
$domnode = $dom->importNode($domnode, true);
$dom->appendChild($domnode);
?>
但是,切换回来很简单。
<?php
//$dom 是一个 DOMDocument 实例
$xml = simplexml_import_dom($dom);
?>
使用 SimpleXMLElement 添加 CDATA 节点非常有用(像 addChild 一样使用它)
<?php
class My_SimpleXMLElement extends SimpleXMLElement {
public function addChildWithCData($name, $value = NULL) {
$new_child = $this->addChild($name);
$node = dom_import_simplexml($new_child);
$no = $node->ownerDocument;
$node->appendChild($no->createCDATASection($value));
return $new_child;
}
}