【问题标题】:Merge two XML files with reference ID合并两个带有参考 ID 的 XML 文件
【发布时间】:2018-07-28 20:48:32
【问题描述】:

我有两个 XML,有人可以帮助我如何将它与 PHP 合并到一个 XML 中。 两个 XML 具有相同的 .我需要将它与所有节点合并,使用相同的“ProductCode”引用数据。

内容 XML1:

<Table>
<ProductCode>0352097</ProductCode>
<ProductName>Product Name</ProductName>
<ProductType>Product Type</ProductType>
<Brand>Brand</Brand>
<PartNo>Q3960A</PartNo>
</Table>

内容 XML2:

<Table>
<ProductCode>0120392</ProductCode>
<ProductListPrice>XXX</ProductListPrice>
<ProductDiscount>YYYY</ProductDiscount>
<ProductPartnerPrice>ZZZ</ProductPartnerPrice>
</Table>

我想完成这个:

<Table>
<ProductCode>0352097</ProductCode>
<ProductName>Product Name</ProductName>
<ProductType>Product Type</ProductType>
<Brand>Brand</Brand>
<PartNo>Q3960A</PartNo>
<ProductListPrice>XXX</ProductListPrice>
<ProductDiscount>YYYY</ProductDiscount>
<ProductPartnerPrice>ZZZ</ProductPartnerPrice>
</Table>

【问题讨论】:

    标签: php xml


    【解决方案1】:

    DOM 允许您将节点从一个文档导入另一个文档,并且您可以使用 Xpath 选择节点。

    $target = new DOMDocument();
    $target->preserveWhiteSpace = FALSE;
    $target->loadXml($xml1);
    $targetXpath = new DOMXpath($target);
    
    $source = new DOMDocument();
    $source->loadXml($xml2);
    $sourceXpath = new DOMXpath($source);
    foreach ($targetXpath->evaluate('//Table') as $tableNode) {
      $productCode = $targetXpath->evaluate('string(ProductCode)', $tableNode);
      foreach ($sourceXpath->evaluate('//Table[ProductCode="'.$productCode.'"]/*[not(self::ProductCode)]') as $node) {
        $tableNode->appendChild(
          $target->importNode($node, TRUE)
        );
      }
    }
    
    $target->formatOutput = TRUE;
    echo $target->saveXml();
    

    DOMDocument::importNode() 复制一个节点,包括其所有属性(标签名称、命名空间)、属性和后代节点。

    【讨论】:

    • 谢谢,但有没有正确的方法来调用 XML,例如:$target-&gt;loadXml('GetProductslist.aspx.xml'); 或者是别的什么,因为我收到这些行的日志错误。谢谢
    • 作品:),非常感谢。我只是把 $target->load('GetProductslist.aspx.xml');并在顶部标题('Content-type:text/xml');
    • 是的 DOMDocument::loadXml() 用于 XML 字符串,DOMDocument::load() 用于 XML 文件。
    【解决方案2】:

    您可以使用simplexml_load_string 函数和SimpleXMLElement 类来处理XML。

    片段

    $xml1 = '<Table>
    <ProductCode>0352097</ProductCode>
    <ProductName>Product Name</ProductName>
    <ProductType>Product Type</ProductType>
    <Brand>Brand</Brand>
    <PartNo>Q3960A</PartNo>
    </Table>';
    
    $xml2 = '<Table>
    <ProductCode>0120392</ProductCode>
    <ProductListPrice>XXX</ProductListPrice>
    <ProductDiscount>YYYY</ProductDiscount>
    <ProductPartnerPrice>ZZZ</ProductPartnerPrice>
    </Table>';
    
    //Converting to array
    $xml1 = (array) simplexml_load_string($xml1);
    $xml2 = (array) simplexml_load_string($xml2);
    array_shift($xml2); //Removing Product Code From Second XML
    //Merging Together
    $resultAsArray =  array_merge($xml1, $xml2);
    //Flipping array
    $flipped = array_flip($resultAsArray);
    
    //Converting Back To The XML
    $resultXML = new SimpleXMLElement('<Table/>');
    array_walk($flipped, array ($resultXML, 'addChild'));
    print $resultXML->asXML();
    

    输出

    <?xml version="1.0"?>
    <Table>
       <ProductCode>0352097</ProductCode>
       <ProductName>Product Name</ProductName>
       <ProductType>Product Type</ProductType>
       <Brand>Brand</Brand>
       <PartNo>Q3960A</PartNo>
       <ProductListPrice>XXX</ProductListPrice>
       <ProductDiscount>YYYY</ProductDiscount>
       <ProductPartnerPrice>ZZZ</ProductPartnerPrice>
    </Table>
    

    查看演示Here

    参考:
    simplexml_load_string
    SimpleXMLElement

    【讨论】:

    • @PozitivneVijesti 你看演示了吗??? 3v4l.org/95VhB,要根据ProductCode合并数据吗?
    【解决方案3】:

    使用 SimpleXML 处理文档是最简单的选择。这假设您有两个要合并的部件列表,并使用 XPath 在第一个文档中查找与第二个文档中要更新的部件匹配的数据。然后它只是将所有内容(除了 ProductCode)复制到基本文档中。

    所以用一些简单的测试数据...

    $xml1 = "<Products>
        <Table>
            <ProductCode>0352097</ProductCode>
            <ProductName>Product Name</ProductName>
            <ProductType>Product Type</ProductType>
            <Brand>Brand</Brand>
            <PartNo>Q3960A</PartNo>
        </Table>
        <Table>
            <ProductCode>0352098</ProductCode>
            <ProductName>Product Name2</ProductName>
            <ProductType>Product Type2</ProductType>
            <Brand>Brand2</Brand>
            <PartNo>Q3960A2</PartNo>
        </Table>
    </Products>";
    
    $xml2 = "<Products>
        <Table>
            <ProductCode>0352097</ProductCode>
            <ProductListPrice>p1</ProductListPrice>
            <ProductDiscount>pp1</ProductDiscount>
            <ProductPartnerPrice>1</ProductPartnerPrice>
        </Table>
        <Table>
            <ProductCode>0352098</ProductCode>
            <ProductListPrice>p2</ProductListPrice>
            <ProductDiscount>pp2</ProductDiscount>
            <ProductPartnerPrice>2</ProductPartnerPrice>
        </Table>
    </Products>";
    

    代码归结为...

    $base = simplexml_load_string($xml1);
    $add = simplexml_load_string($xml2);
    
    foreach ( $add->Table as $addData )    {
        // Find the corresponding element (take the first match using [0])
        $addTo = $base->xpath("//Table[ProductCode='{$addData->ProductCode}']")[0];
        foreach ( $addData->children() as $name => $value )    {
            if ($name != "ProductCode") {
                $addTo->addChild($name, $value);
            }
        }
    }
    
    echo $base->asXML();
    

    请注意,这仅适用于平面结构,如果您有任何属性或更复杂的数据结构,则需要有不同的解决方案。

    【讨论】:

    • 我不能调用这个脚本。 &lt;?php $base = simplexml_load_string('GetProductslist.aspx.xml'); $add = simplexml_load_string('GetProductsPriceList.aspx.xml'); foreach ( $add-&gt;Table as $addData ) { // Find the corresponding element (take the first match using [0]) $addTo = $base-&gt;xpath("//Table[ProductCode='{$addData-&gt;ProductCode}']")[0]; foreach ( $addData-&gt;children() as $name =&gt; $value ) { if ($name != "ProductCode") { $addTo-&gt;addChild($name, $value); } } } echo $base-&gt;asXML(); ?&gt;
    • 使用simplexml_load_string()处理数据的字符串,如果你想加载文件 - 你需要使用simplexml_load_file()
    猜你喜欢
    • 2021-01-01
    • 2013-05-23
    • 2011-06-23
    • 1970-01-01
    • 2021-12-18
    • 2020-12-16
    • 2011-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多