使用 SimpleXML/DOM 通过 php 将节点从一个 XML 复制到另一个
Using SimpleXML/DOM to copy node from one XML to another via php
我目前正在尝试将节点从一个 XML 复制到另一个。假设我们有 1.xml 如下:
///THIS IS 1.XML
<SuccessResponse>
<Body>
<Orders>
<Order>
<OrderId>123456789</OrderId>
...
</Order>
<Order>
<OrderId>987654321</OrderId>
...
</Order>
</Orders/>
</Body>
</SuccessResponse>
和2.xml如下:
<SuccessResponse>
<Body>
<Orders>
<Order>
<OrderId>123456789</OrderId>
<OrderItems>
<OrderItem>
...
</OrderItem>
<OrderItem>
...
</OrderItem>
</OrderItems>
</Order>
<Order>
<OrderId>987654321</OrderId>
<OrderItems>
<OrderItem>
...
</OrderItem>
<OrderItem>
...
</OrderItem>
</OrderItems>
</Order>
</Orders/>
</Body>
</SuccessResponse>
我想从 2.xml 中获取每个 <OrderItems>
节点及其所有子节点,并附加到 1.xml 中的正确节点。两个 XML 都将按特定顺序排列,因此第一个标签将具有相同的 ,我创建了一个包含所有这些的数组。到目前为止,我已经写了这个:
$idsarray = range(0, count($ids)-1); //idsarray is array of order Ids. this transforms into a list: 0, 1... etc. counting how many orders i have requested
$itemsxml = new SimpleXMLElement($orderitemresponse); //$orderitemresponse is XML string with 2.xml
$ordersxml = new SimpleXMLElement($getordersRESPONSE); //$getordersRESPONSE is XML string with 1.xml
foreach ($idsarray as $orderno) {
$item = $itemsxml->Body->Orders->Order[$orderno]->OrderItems;
$ordersxml->Body->Orders->Order[$orderno]->addChild('Items');
$ordersxml->Body->Orders->Order[$orderno]->Items = $item;
}
echo $ordersxml->asXML();
这在我需要的地方正确地附加了一个 'Items',但是从 foreach 函数的最后一行发送的信息似乎不起作用,因为 'Items' 标记在之后是空的运行 脚本。
我可能需要恢复到 DOM XML 操作来实现我正在尝试的,但我更熟悉 SimpleXML 表示法所以我想我会试试这个方法。困难在于 OrderId 123456789 的项目需要按照正确的顺序附加。非常感谢任何指针。到达时,我将使用正确的解决方案更新 post。我知道使用 php DOM,我可以使用 xpath 导航到正确的正确节点,但是我不确定如何继续这个,因为 OrderId 没有存储为属性。我使用 DOM 手册编写了这段摘录,但是我不确定如何继续将节点附加到正确的位置。目前它只是在文档末尾添加一个子项。
我对 DOM XML 处理的问题是如何导航到 SuccessResponse->Body->Orders->OrderId 并将特定文本分配给该节点,例如 123456789,然后追加到 OrderId 之前的节点,因此作为 CHILD 追加到 Orders
$itemxml = new DOMDocument;
$itemxml->formatOutput = true;
$itemxml = DOMDocument::loadXML($orderitemresponse);
$orderxml = new DOMDocument;
$orderxml->formatOutput = true;
$orderxml = DOMDocument::loadXML($getordersRESPONSE);
$idsarray = range(0, count($ids)-1); //creates counting total orders
foreach ($idsarray as $orderno) {
$i = $itemxml->getElementsByTagName("OrderItems")[$orderno];
$node = $orderxml->importNode($i, true);
$orderxml->documentElement->appendChild($node);
}
echo $orderxml->saveXML();
更新:我相信我已经解决了这个问题。有兴趣者:
$itemxml = new DOMDocument;
$itemxml->formatOutput = true;
$itemxml = DOMDocument::loadXML($orderitemresponse);
$orderxml = new DOMDocument;
$orderxml->formatOutput = true;
$orderxml = DOMDocument::loadXML($getordersRESPONSE);
$idsarray = range(0, count($ids)-1); //creates counting total orders
foreach ($idsarray as $orderno) {
$i = $itemxml->getElementsByTagName("OrderItems")[$orderno];
$node = $orderxml->importNode($i, true);
$parent = $orderxml->getElementsByTagName("Order")[$orderno];
$parent->appendChild($node);
}
echo $orderxml->saveXML();
您可以使用 Xpath 表达式来匹配 OrderId
值,使它更稳定一些。
// bootstrap the DOMs
$sourceDocument = new DOMDocument();
$sourceDocument->loadXML($itemsXML);
$sourceXpath = new DOMXpath($sourceDocument);
$targetDocument = new DOMDocument();
$targetDocument->loadXML($targetXML);
$targetXpath = new DOMXpath($targetDocument);
// iterate the target orders
foreach ($targetXpath->evaluate('//Order') as $order) {
// get the order id
$orderId = $targetXpath->evaluate('string(OrderId)', $order);
// iterate the OrderItems elements for a specific order id
foreach($sourceXpath->evaluate('//Order[OrderId="'.$orderId.'"]/OrderItems') as $items) {
// import and append
$order->appendChild($targetDocument->importNode($items, TRUE));
}
}
echo $targetDocument->saveXML();
我目前正在尝试将节点从一个 XML 复制到另一个。假设我们有 1.xml 如下:
///THIS IS 1.XML
<SuccessResponse>
<Body>
<Orders>
<Order>
<OrderId>123456789</OrderId>
...
</Order>
<Order>
<OrderId>987654321</OrderId>
...
</Order>
</Orders/>
</Body>
</SuccessResponse>
和2.xml如下:
<SuccessResponse>
<Body>
<Orders>
<Order>
<OrderId>123456789</OrderId>
<OrderItems>
<OrderItem>
...
</OrderItem>
<OrderItem>
...
</OrderItem>
</OrderItems>
</Order>
<Order>
<OrderId>987654321</OrderId>
<OrderItems>
<OrderItem>
...
</OrderItem>
<OrderItem>
...
</OrderItem>
</OrderItems>
</Order>
</Orders/>
</Body>
</SuccessResponse>
我想从 2.xml 中获取每个 <OrderItems>
节点及其所有子节点,并附加到 1.xml 中的正确节点。两个 XML 都将按特定顺序排列,因此第一个标签将具有相同的 ,我创建了一个包含所有这些的数组。到目前为止,我已经写了这个:
$idsarray = range(0, count($ids)-1); //idsarray is array of order Ids. this transforms into a list: 0, 1... etc. counting how many orders i have requested
$itemsxml = new SimpleXMLElement($orderitemresponse); //$orderitemresponse is XML string with 2.xml
$ordersxml = new SimpleXMLElement($getordersRESPONSE); //$getordersRESPONSE is XML string with 1.xml
foreach ($idsarray as $orderno) {
$item = $itemsxml->Body->Orders->Order[$orderno]->OrderItems;
$ordersxml->Body->Orders->Order[$orderno]->addChild('Items');
$ordersxml->Body->Orders->Order[$orderno]->Items = $item;
}
echo $ordersxml->asXML();
这在我需要的地方正确地附加了一个 'Items',但是从 foreach 函数的最后一行发送的信息似乎不起作用,因为 'Items' 标记在之后是空的运行 脚本。
我可能需要恢复到 DOM XML 操作来实现我正在尝试的,但我更熟悉 SimpleXML 表示法所以我想我会试试这个方法。困难在于 OrderId 123456789 的项目需要按照正确的顺序附加。非常感谢任何指针。到达时,我将使用正确的解决方案更新 post。我知道使用 php DOM,我可以使用 xpath 导航到正确的正确节点,但是我不确定如何继续这个,因为 OrderId 没有存储为属性。我使用 DOM 手册编写了这段摘录,但是我不确定如何继续将节点附加到正确的位置。目前它只是在文档末尾添加一个子项。
我对 DOM XML 处理的问题是如何导航到 SuccessResponse->Body->Orders->OrderId 并将特定文本分配给该节点,例如 123456789,然后追加到 OrderId 之前的节点,因此作为 CHILD 追加到 Orders
$itemxml = new DOMDocument;
$itemxml->formatOutput = true;
$itemxml = DOMDocument::loadXML($orderitemresponse);
$orderxml = new DOMDocument;
$orderxml->formatOutput = true;
$orderxml = DOMDocument::loadXML($getordersRESPONSE);
$idsarray = range(0, count($ids)-1); //creates counting total orders
foreach ($idsarray as $orderno) {
$i = $itemxml->getElementsByTagName("OrderItems")[$orderno];
$node = $orderxml->importNode($i, true);
$orderxml->documentElement->appendChild($node);
}
echo $orderxml->saveXML();
更新:我相信我已经解决了这个问题。有兴趣者:
$itemxml = new DOMDocument;
$itemxml->formatOutput = true;
$itemxml = DOMDocument::loadXML($orderitemresponse);
$orderxml = new DOMDocument;
$orderxml->formatOutput = true;
$orderxml = DOMDocument::loadXML($getordersRESPONSE);
$idsarray = range(0, count($ids)-1); //creates counting total orders
foreach ($idsarray as $orderno) {
$i = $itemxml->getElementsByTagName("OrderItems")[$orderno];
$node = $orderxml->importNode($i, true);
$parent = $orderxml->getElementsByTagName("Order")[$orderno];
$parent->appendChild($node);
}
echo $orderxml->saveXML();
您可以使用 Xpath 表达式来匹配 OrderId
值,使它更稳定一些。
// bootstrap the DOMs
$sourceDocument = new DOMDocument();
$sourceDocument->loadXML($itemsXML);
$sourceXpath = new DOMXpath($sourceDocument);
$targetDocument = new DOMDocument();
$targetDocument->loadXML($targetXML);
$targetXpath = new DOMXpath($targetDocument);
// iterate the target orders
foreach ($targetXpath->evaluate('//Order') as $order) {
// get the order id
$orderId = $targetXpath->evaluate('string(OrderId)', $order);
// iterate the OrderItems elements for a specific order id
foreach($sourceXpath->evaluate('//Order[OrderId="'.$orderId.'"]/OrderItems') as $items) {
// import and append
$order->appendChild($targetDocument->importNode($items, TRUE));
}
}
echo $targetDocument->saveXML();