将SimpleXMLElement子项复制到另一个对象

问题描述 投票:0回答:1

鉴于两个SimpleXMLElement对象的结构如下(相同):

$ OBJ1

object SimpleXMLElement {
    ["@attributes"] =>
    array(0) {
    }
    ["event"] =>
    array(1) {
        [0] =>
        object(SimpleXMLElement) {
            ["@attributes"] =>
            array(1) {
                ["url"] =>
                string "example.com"
            }
        }
    }
}

$ obj2

object SimpleXMLElement {
    ["@attributes"] =>
    array(0) {
    }
    ["event"] =>
    array(1) {
        [0] =>
        object(SimpleXMLElement) {
            ["@attributes"] =>
            array(1) {
                ["url"] =>
                string "another-example.com"
            }
        }
    }
}

我试图将所有子event项目从第二个对象复制到第一个对象,如下所示:

foreach ($obj2->event as $event) {
    $obj1->event[] = $event
}

它们移动,但复制的对象现在是空的。

$ OBJ1

object SimpleXMLElement {
    ["@attributes"] =>
    array(0) {
    }
    ["event"] =>
    array(2) {
        [0] =>
        object(SimpleXMLElement) {
            ["@attributes"] =>
            array(1) {
                ["url"] =>
                string "example.com"
            }
        }
        [1] =>
        object(SimpleXMLElement) {
        }
    }
}
php simplexml
1个回答
1
投票

SimpleXML的编辑功能相当有限,在这种情况下,您正在执行的任务和->addChild都只能设置新元素的文本内容,而不能设置其属性和子元素。

这可能是您需要更复杂的DOM API的强大功能的一种情况。幸运的是,你可以将PHP中的两个混合使用几乎没有任何惩罚,使用dom_import_simplexmlsimplexml_import_dom切换到另一个包装器。

一旦你有一个DOM表示,你可以使用the appendChild method of DOMNode添加一个完整的节点,但是有一个问题 - 你只能添加“拥有”同一文档的节点。因此,您必须首先在您要编辑的文档上调用the importNode method

总而言之,你得到这样的东西:

// Set up the objects you're copying from and to
// These don't need to be complete documents, they could be any element
$obj1 = simplexml_load_string('<foo><event url="example.com" /></foo>');
$obj2 = simplexml_load_string('<foo><event url="another.example.com" /></foo>');

// Get a DOM representation of the root element we want to add things to
// Note that $obj1_dom will always be a DOMElement not a DOMDocument, 
//   because SimpleXML has no "document" object
$obj1_dom = dom_import_simplexml($obj1);

// Loop over the SimpleXML version of the source elements
foreach ($obj2->event as $event) {
    // Get the DOM representation of the element we want to copy
    $event_dom = dom_import_simplexml($event);
    // Copy the element into the "owner document" of our target node
    $event_dom_copy = $obj1_dom->ownerDocument->importNode($event_dom, true);
    // Add the node as a new child
    $obj1_dom->appendChild($event_dom_adopted);
}

// Check that we have the right output, not trusting var_dump or print_r
// Note that we don't need to convert back to SimpleXML 
// - $obj1 and $obj1_dom refer to the same data internally
echo $obj1->asXML();
© www.soinside.com 2019 - 2024. All rights reserved.