【问题标题】:extract distinct tag value from xml file using php使用php从xml文件中提取不同的标签值
【发布时间】:2014-01-19 16:49:49
【问题描述】:

我有一个联系方式的xml文件如下

contacts.xml

<?xml version="1.0"?>
<contacts>
  <contact>
    <contact_no>9782547000</contact_no>
    <Name>xName</Name>
    <Email>xEmail@gmail.com</Email>
  </contact>
   <contact>
    <contact_no>9782547000</contact_no>
    <Name>yName</Name>
    <Email>xEmail@gmail.com</Email>
  </contact>
   <contact>
    <contact_no>9782547012</contact_no>
    <Name>xName</Name>
    <Email>xEmail@gmail.com</Email>
  </contact>
   <contact>
    <contact_no>9782547011</contact_no>
    <Name>xName</Name>
    <Email>xEmail@gmail.com</Email>
  </contact>
   <contact>
    <contact_no>9782547012</contact_no>
    <Name>xName</Name>
    <Email>xEmail@gmail.com</Email>
  </contact>
   <contact>
    <contact_no>9782547000</contact_no>
    <Name>xName</Name>
    <Email>xEmail@gmail.com</Email>
  </contact>
 </contacts>

在这里您可以看到标签contact_no 有一些重复。我想删除重复并只存储不同的联系人不使用 php 保存 xml 文件

申请流程后,xml 将如下所示,其中包含三个不同的联系号码。

contact.xml

 <?xml version="1.0"?>
    <contacts>
      <contact>
        <contact_no>9782547000</contact_no>
        <Name>xName</Name>
        <Email>xEmail@gmail.com</Email>
      </contact>

       <contact>
        <contact_no>9782547012</contact_no>
        <Name>xName</Name>
        <Email>xEmail@gmail.com</Email>

      </contact>
       <contact>
        <contact_no>9782547011</contact_no>
        <Name>xName</Name>
        <Email>xEmail@gmail.com</Email>
      </contact>

     <contacts>

我在 DOMDocument 和 simpleXMLElement 中进行了搜索,但找不到成功。 是否有任何功能或方法来实现这一点。提前致谢。

【问题讨论】:

  • 为什么要否决这个问题?
  • 如果有人没有建议。停止投票。
  • 您的contacts.xml 语法错误。示例:&lt;Email&gt; 必须以 &lt;/Email&gt; 而不是 &lt;/msg&gt; 结尾。
  • 请提供有效的xml
  • 我错误地更新了它。

标签: php xml


【解决方案1】:

我通过 DomDocument 开发了这段代码。 这是我命名为contact.xml 的xml 文件。请看一下。

<?xml version="1.0" encoding="UTF-8"?>
<contacts>
    <contact>
        <contact_no>9782547000</contact_no>
        <Name>xName</Name>
        <Email>xEmail@gmail.com</Email>
    </contact>
    <contact>
        <contact_no>9782547000</contact_no>
        <Name>yName</Name>
        <Email>xEmail@gmail.com</Email>
    </contact>
    <contact>
        <contact_no>9782547012</contact_no>
        <Name>xName</Name>
        <Email>xEmail@gmail.com</Email>
    </contact>
    <contact>
        <contact_no>9782547011</contact_no>
        <Name>xName</Name>
        <Email>xEmail@gmail.com</Email>
    </contact>
    <contact>
        <contact_no>9782547012</contact_no>
        <Name>xName</Name>
        <Email>xEmail@gmail.com</Email>
    </contact>
    <contact>
        <contact_no>9782547000</contact_no>
        <Name>xName</Name>
        <Email>xEmail@gmail.com</Email>
    </contact>
    </contacts>

现在我已经为它开发了这样的功能:

<?php
        $dom=new DOMDocument();
        $dom->load("contact.xml");
        $tt=$dom->getElementsByTagName("contact_no");
        foreach ($tt as $tt1){
            $dt= new DOMXPath($dom);
            $dtlist=$dt->query('/contacts/contact/contact_no[text()="'.$tt1->nodeValue.'"]');
            $count=0;
            foreach($dtlist as $tmt){
                if($count!=0){
                    $tmt->parentNode->parentNode->removeChild($tmt->parentNode);
                }
                $count++;
            }
        }
        $dom->saveXML();
        $dom->save("contact.xml");
        ?>

希望您会喜欢该代码。如果您有任何疑问,请告诉我。

【讨论】:

    【解决方案2】:

    使用simplexmlxpath

    $xml = simplexml_load_string($x); // assume XML in $x
    
    // create array with all non-unique <contact_no>
    $ids = $xml->xpath("/contacts/contact/contact_no");
    $ids = array_diff(array_count_values(array_map("strval", $ids)), array("1"));
    
    // select each non-unique entry and delete it
    foreach ($ids as $id => $count) {   
        $results = $xml->xpath("/contacts/contact[contact_no = '$id']");
        for ($i = $count; $i > 0; $i--) unset($results[$i][0]); 
    } 
    

    看到它的工作:https://eval.in/84939

    评论
    line 04:全选&lt;contact_no&gt;并放入array $ids
    line 05:这些是对象,所以我们...
    1.使用array_map()将它们转换为string
    2. 使用array_count_values()contact_no 设为key 并将其计数为value
    3.使用array_diff()删除所有唯一元素(value = 1
    line 09:选择所有&lt;contact&gt;,其no存储在$id进入$results
    line 10:循环通过@ 987654343@ 和 unset() 都是 &lt;contact&gt; 但只有一个

    【讨论】:

      【解决方案3】:

      我们可以通过使用 PHP 的 SimpleXMl 函数进行 xml 操作并使用循环来解决这个问题,当contact_no 匹配时,我们可以删除父元素。

          <?php
      
              $str = <<<_END
              <?xml version="1.0"?>
              <contacts>
        <contact>
          <contact_no>9782547000</contact_no>
          <Name>xName</Name>
          <Email>xEmail@gmail.com</Email>
        </contact>
         <contact>
          <contact_no>9782547000</contact_no>
          <Name>yName</Name>
          <Email>xEmail@gmail.com</Email>
        </contact>
         <contact>
          <contact_no>9782547012</contact_no>
          <Name>xName</Name>
          <Email>xEmail@gmail.com</Email>
        </contact>
         <contact>
          <contact_no>9782547011</contact_no>
          <Name>xName</Name>
          <Email>xEmail@gmail.com</Email>
        </contact>
         <contact>
          <contact_no>9782547012</contact_no>
          <Name>xName</Name>
          <Email>xEmail@gmail.com</Email>
        </contact>
         <contact>
          <contact_no>9782547000</contact_no>
          <Name>xName</Name>
          <Email>xEmail@gmail.com</Email>
        </contact>
       <contacts>
              _END;
          $xml=simplexml_load_string($str);
      
          $seen=array();
      
          $len=$xml->contact->count();
          for($i=0;$i<$len;$i++){
              $key=(string) $xml->contact[$i]->contact_no;
              if (isset($seen[$key])) {
                  unset($xml->contact[$i]);
                  $len--;
                  $i--;
              }else{
                  $seen[$key]=1;
              }
          }
      
          echo $xml->asXML();
          ?>
      

      如果您有任何疑问,请告诉我。

      【讨论】:

      • 谢谢,但我不想使用数组或遍历文件的所有标签,因为文件可能有很多记录。
      • 为什么没有数组?顺便提一句。 @Avi 至少发布您从中获取此代码的链接,因为这不是您自己的。 stackoverflow.com/questions/9922039/…
      • @dan 如果我使用数组,如果我的 xml 文件有大量记录(在 lacs 中),则需要大量内存和处理时间
      • @dan 谢谢,一定会的。
      • @Satish Sharma 在没有数组的情况下在其下发布另一个答案来回答您的问题。如果您有任何疑问,请查看并更新我。
      猜你喜欢
      • 2014-05-09
      • 1970-01-01
      • 2012-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多