我有两个具有这种结构的XML文件:
first.xml
<items>
<item>
<id>foo</id>
<desc>lorem ipsum</desc>
</item>
<item>
<id>boo</id>
<desc>lorem ipsum</desc>
</item>
</items>
second.xml
<item_list>
<item id="foo">
<stock_quantity>20</stock_quantity>
</item>
<item id="boo">
<stock_quantity>11</stock_quantity>
</item>
</item_list>
并且我需要通过id组合它们,以便输出文件看起来像这样:
output.xml
<items>
<item>
<id>foo</id>
<desc>lorem ipsum</desc>
<stock_quantity>20</stock_quantity>
</item>
<item>
<id>boo</id>
<desc>lorem ipsum</desc>
<stock_quantity>11</stock_quantity>
</item>
</items>
我需要使用PHP和XML DOMDocument。你有办法吗?
答案 0 :(得分:0)
您可以使用simplexml库来实现这一目标,
// loading xml to object from file
$xml1 = simplexml_load_file("first.xml") or die("Error: Cannot create object");
$xml2 = simplexml_load_file("second.xml") or die("Error: Cannot create object");
// its core xml iterator for simplexml library
foreach ($xml1->children() as $items1) {
$id = trim($items1->id); // trim to check with id matched in 2.xml
foreach ($xml2->children() as $items2) { // iterating children of 2.xml
if ($items2[0]['id'] == $id) { // simply checking attribute of id in 2.xml with 1.xml's id value
foreach ($items2 as $key => $value) {
$items1->addChild($key, (string) ($value)); // adding children to 1.xml object
}
}
}
}
$xml1->asXml('output.xml'); // generating https://www.php.net/manual/en/simplexmlelement.asxml.php
答案 1 :(得分:0)
使用DOMDocument并具有将节点从一个文档复制到另一个文档的功能,使您可以将库存中的节点直接插入到主要XML。
表达式//item[@id='boo']/stock_quantity
表示在<stock_quantity>
元素中找到具有属性的<item>
元素,而不是循环查找匹配的记录,而是使用XPath搜索匹配的记录。的id='boo'
$main = new DOMDocument();
$main->load("main.xml");
$add = new DOMDocument();
$add->load("stock.xml");
$searchAdd = new DOMXPath($add);
// Find the list of items
$items = $main->getElementsByTagName("item");
foreach ( $items as $item ) {
// Exract the value of the id node
$id = $item->getElementsByTagName("id")[0]->nodeValue;
// Find the corresponding node in the stock file
$stockQty = $searchAdd->evaluate("//item[@id='{$id}']/stock_quantity");
// Import the <stock_quantity> node (and all contents)
$copy = $main->importNode($stockQty[0], true);
// Add the imported node
$item->appendChild($copy);
}
echo $main->saveXML();
答案 2 :(得分:0)
请考虑XSLT,这是一种专用语言(如SQL),旨在转换XML文件,例如您的特定最终用途需求。与许多通用语言一样,PHP可以使用特殊的库php-xsl类(需要启用.ini扩展名)将XSLT 1.0作为较低层运行。
XSLT (另存为.xsl文件,一个特殊的.xml文件;以下假定同一目录中有第二个XML)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- IDENTITY TRANSFORM -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- ADD NODE BY CORRESPONDING id VALUE -->
<xsl:template match="item">
<xsl:copy>
<xsl:variable name="curr_id" select="id"/>
<xsl:apply-templates select="@*|node()"/>
<xsl:copy-of select="document('second.xml')/item_list/item[@id = $curr_id]/*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
PHP (仅引用第一个XML)
// Load the XML source and XSLT file
$xml = new DOMDocument;
$xml->load('first.xml');
$xsl = new DOMDocument;
$xsl->load('XSLTScript.xsl');
// Configure transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
// Transform XML source
$newXML = new DOMDocument;
$newXML = $proc->transformToXML($xml);
echo $newXML;
// Save output to file
$xmlfile = 'output.xml';
file_put_contents($xmlfile, $newXML);