将外部XML文件合并为一个和orderby

时间:2015-04-09 19:03:54

标签: php xml output

我有以下PHP函数将多个外部XML文件合并到一个文件中:

<?php
    function combineXML($file) 
    { 
        global $xmlstr; 

        $xml = simplexml_load_file($file); 

        foreach($xml as $element) 
            $xmlstr .= $element->asXML(); 
    } 

    $files[] = "file1.xml"; 
    $files[] = "file2.xml"; 

    $xmlstr = '<productItems>';

    foreach ($files as $file) 
        combineXML($file); 

    $xmlstr .= '</productItems>'; 

    $xml = simplexml_load_string($xmlstr); 
    $bytes = file_put_contents("output.xml", $xml->asXML());    
?>

是否也可以重新订购Feed?就像最后修改一样?因此,按 lastmodified 文件系统日期排序。

1 个答案:

答案 0 :(得分:3)

您没有提供XML示例,所以让我们假设一些简单的结构:

$xmls = [ 
'<productItems>
  <item>
    <title>Item 1</title>
    <lastmodified>1</lastmodified>
  </item>
</productItems>',
'<productItems>
  <item>
    <title>Item 2</title>
    <lastmodified>2</lastmodified>
  </item>
</productItems>'
];

合并XML

我更喜欢使用DOM。 (这更容易,因为这里没有自动映射)。

首先创建目标文档并添加文档元素节点:

$merged = new DOMDocument();
$merged->appendChild($merged->createElement('productItems'));

接下来迭代XML,将它们加载到DOM中,并将文档元素的所有子节点复制到目标文档。

foreach ($xmls as $xml) {
  $source = new DOMDocument();
  $source->loadXml($xml);
  foreach ($source->documentElement->childNodes as $node) {
    $merged->documentElement->appendChild(
      $merged->importNode($node, TRUE)
    );
  }
}

允许格式化并保存合并的XML:

$merged->formatOutput = true;
echo $merged->saveXml();

输出:

<?xml version="1.0"?>
<productItems>
  <item>
    <title>Item 1</title>
    <modified>1</modified>
  </item>    
  <item>
    <title>Item 2</title>
    <modified>2</modified>
  </item>
</productItems>

使用文件

如果您使用的是文件,则必须使用DOMDocument::load()DOMDocument::save()DOMDocument::loadXml()/saveXml()用于XML字符串。

排序节点

使用XPath从源文档中获取item个节点,并将节点列表转换为数组:

$xpath = new DOMXPath($merged);
$products = iterator_to_array($xpath->evaluate('//item'));

使用usort对数组进行排序。使用XPath,您可以在节点的上下文中获取任何数据:

usort(
  $products,
  function($nodeOne, $nodeTwo) use ($xpath) {
    return strnatcmp(
      $xpath->evaluate('string(modified)', $nodeTwo),
      $xpath->evaluate('string(modified)', $nodeOne)
    );    
  }
);

创建目标文档并将节点复制到其中:

$sorted= new DOMDocument();
$sorted->appendChild($sorted->createElement('productItems'));
foreach ($products as $node) {
  $sorted->documentElement->appendChild(
    $sorted->importNode($node, TRUE)
  );
}

$sorted->formatOutput = true;
echo $sorted->saveXml();

输出:

<?xml version="1.0"?>
<productItems>
  <item>
    <title>Item 2</title>
    <modified>2</modified>
  </item>
  <item>
    <title>Item 1</title>
    <modified>1</modified>
  </item>
</productItems>