【问题标题】:How to update Document-A XML nodes with Document-B XML nodes using php如何使用 php 用 Document-B XML 节点更新 Document-A XML 节点
【发布时间】:2017-02-06 16:37:45
【问题描述】:

我有两个 XML 文件:一个来自客户端,另一个来自 db 查询。 db XML 文件具有以下结构:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<metadata xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <tags>
        <title>Wordsleuth (2006, volume 3, 4): The Dictionary: Disapproving Schoolmarm or Accurate Record?</title>
        <alias>favart/wordsleuth-2006-volume-3-4-the-dictionary-disapproving-schoolmarm-or-accurate-record</alias>
        <id>4361</id>
    </tags>
</metadata>

客户端 XML 具有以下结构:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<metadata xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <tags>
        <title>Wordsleuth (2006, vol. 3, 4): The Dictionary: Disapproving Schoolmarm or Accurate Record? – Search by Title – Favourite Articles – TERMIUM Plus® – Translation Bureau</title>
        <description>A Language Update article on the role that the dictionary plays in language usage.</description>
        <keywords>language usage; dictionaries</keywords>
        <subject>English language; Terminology</subject>
    </tags>
</metadata>

每个都有大约 200 个“标签”元素。在从herehere 得到一些提示并参考 PHP 手册后,我第一次破解它产生了这个:

$client = 'C:\xampp\htdocs\wetkit\sites\all\modules\my_metatags\favart.xml';
$db = 'C:\xampp\htdocs\wetkit\sites\all\modules\my_metatags\tmp\from db\favart_db.xml';
$c_xmlstr = file_get_contents($client);
$d_xmlstr = file_get_contents($db);
$favartdoc_db = new DomDocument('1.0','UTF-8');
$favartdoc_cl = new DomDocument('1.0','UTF-8');
$favartdoc_db->loadXML($d_xmlstr);
$favartdoc_cl->loadXML($c_xmlstr);
for ($i=0;$i==$favartdoc_cl->getElementsByTagName('title')->count; $i++){
    $c_nodes = $x_favartdoc_cl->query('/metadata/tags/title');
    $c_node = $c_nodes->item($i);
for ($j=0; $j==$favartdoc_db->getElementsByTagName('title')->count; $j++){
        $d_nodes = $x_favartdoc_db->query('/metadata/tags/title');
        $d_node = $d_nodes->item($j);
        if(stripos(trim($c_node->nodeValue), trim($d_node->nodeValue))===0){
        $favartdoc_cl->replaceChild($d_node,$c_node);
        if($i==($c_nodes->count)){break;};
        }
}
$favartdoc_cl->saveXML();
}

此代码运行,不产生任何错误,并且什么也不做。结尾有一个回显语句

echo "\n\n" . "THE TOTAL NUMBER OF MATCHES EQUALS " . $i . " IN " . $j . " NODES." . "\n";

生成此消息:

匹配的总数等于 1 比 1 节点。

第二种更简单的方法产生了这个:

$favartdoc_db = new DomDocument('1.0','UTF-8');
$favartdoc_cl = new DomDocument('1.0','UTF-8');
$favartdoc_db->load($db);
$favartdoc_cl->load($client);
$favartdoc_cl->formatOutput = true;
$c_meta_x =  new DOMXpath($favartdoc_cl);
$d_meta_x =  new DOMXpath($favartdoc_db);
foreach ($c_meta_x->query('//tags') as $c_tag){
        foreach ($d_meta_x->query('//tags') as $d_tag){
            if(strncasecmp(trim($c_tag->title), trim($d_tag->title) , strlen(trim($d_tag->title)))===0){
                $c_tag->appendChild($d_tag);
            }           
        }
}
$favartdoc_cl->saveXML();

但这会产生错误:

带有“错误文档错误”消息的异常“DOMException”

通过在将 importNode 附加到 DOM 之前调用 importNode 来纠正该错误的建议仍然会产生相同的错误。

如您所见,我正在尝试不同的字符串匹配函数。最终,我想用数据库中的标题替换客户端 XML 中的标题,或者将数据库 XML 中的整个标记集附加到客户端 XML,然后删除客户端标题元素。

任何帮助将不胜感激。

【问题讨论】:

    标签: php xml


    【解决方案1】:

    这对我有用。

    $client  = 'some\where\somefile.xml';
    $db = 'some\where\someOtherfile.xml';
    
    $c_xmlstr = file_get_contents($client);
    $d_xmlstr = file_get_contents($db);
    
    $doc_db = new DomDocument('1.0','UTF-8');
    $doc_cl = new DomDocument('1.0','UTF-8');
    
    
    $doc_db->loadXML($d_xmlstr);
    $fdoc_cl->loadXML($c_xmlstr);
    
    $x_doc_db = new DOMXpath($doc_db);
    $x_doc_cl = new DOMXpath($doc_cl);
    
    $c_nodes = $x_doc_cl->query('/metadata/tags');
    $c_nodes_titles = $x_doc_cl->query('/metadata/tags/title');
    
        for($i=0;$i<=$c_nodes->length;++$i){
    
          $c_node = $c_nodes->item($i);
          $c_node_title = $c_nodes_titles->item($i);
    
          $d_nodes = $x_doc_db->query('/metadata/tags');
          $d_nodes_titles = $x_doc_db->query('/metadata/tags/title');
          $d_nodes_ids = $x_doc_db->query('/metadata/tags/id');
    
          for($j=0;$j<=$d_nodes->length;++$j){  
    
            $d_node_title = $d_nodes_titles->item($j);
            $d_node_id = $d_nodes_ids->item($j);
    
            if(strncasecmp(trim($c_node_title->textContent),trim($d_node_title->textContent) , strlen(trim($d_node_title->textContent)))===0 && trim($c_node_title->textContent)===trim($d_node_title->textContent)){
    
              $db_id = $doc_cl->createElement("db_id");
              $db_id_val = $doc_cl->createTextNode($d_node_id->nodeValue);
    
              if(!is_null($c_node)){$c_node->appendChild($db_id);}
              if(!is_null($c_node)){$c_node->appendChild($db_id_val);}
    
            }
          }
          if($i===($c_nodes->count) && $j===($d_nodes->count)){break;};
        }
    $doc_cl->saveXML();
    

    【讨论】:

    • 虽然这是创建元素并将它们插入到我期望的位置的工作代码,但我并不幻想有人可以编写更优雅的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2011-06-12
    • 2013-03-02
    • 1970-01-01
    • 2013-02-16
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多