-6

i have a xml file of contact as follows

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>

here you can see that tag contact_no has some duplicate. i want to remove duplicate and store only distinct contact no save the xml file using php

the xml will be as follows with three distinct contact nos after applying process.

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>

i have searches in DOMDocument ad simpleXMLElement but couldn't find success. is there any function or method to implement this. thanks in advance.

michi
  • 6,565
  • 4
  • 33
  • 56
Satish Sharma
  • 9,547
  • 6
  • 29
  • 51

3 Answers3

0

using simplexmland xpath:

$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]); 
} 

see it working: https://eval.in/84939

Comments
line 04: select all <contact_no> and put it into array $ids
line 05: these are objects, so we...
1. use array_map() to convert them to string
2. use array_count_values() to have the contact_no as key and its count as value
3. use array_diff() to remove all unique elements (value = 1)
line 09: select all <contact> with its no stored in $id into $results
line 10: loop through $results and unset() all <contact> but one

michi
  • 6,565
  • 4
  • 33
  • 56
-1

I have developed this code through the DomDocument. This my xml file which i have named contact.xml. Please have a look.

<?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>

Now I have developed the functionality for it like this:

<?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");
        ?>

Hope you will enjoy the code. Please let me know if you have any queries.

-2

We can resolve this by using the SimpleXMl function of PHP for xml operations and using the loop where we can remove the parent element when the contact_no got matched.

    <?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();
    ?>

Let me know if you have any queries.

Satish Sharma
  • 9,547
  • 6
  • 29
  • 51