-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>[email protected]</Email>
  </contact>
   <contact>
    <contact_no>9782547000</contact_no>
    <Name>yName</Name>
    <Email>[email protected]</Email>
  </contact>
   <contact>
    <contact_no>9782547012</contact_no>
    <Name>xName</Name>
    <Email>[email protected]</Email>
  </contact>
   <contact>
    <contact_no>9782547011</contact_no>
    <Name>xName</Name>
    <Email>[email protected]</Email>
  </contact>
   <contact>
    <contact_no>9782547012</contact_no>
    <Name>xName</Name>
    <Email>[email protected]</Email>
  </contact>
   <contact>
    <contact_no>9782547000</contact_no>
    <Name>xName</Name>
    <Email>[email protected]</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>[email protected]</Email>
      </contact>

       <contact>
        <contact_no>9782547012</contact_no>
        <Name>xName</Name>
        <Email>[email protected]</Email>

      </contact>
       <contact>
        <contact_no>9782547011</contact_no>
        <Name>xName</Name>
        <Email>[email protected]</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.

4
  • if anyone has no suggestion. stop to downvote. Commented Jan 2, 2014 at 9:16
  • Your contacts.xml has wrong syntax. Example : <Email> must be end with </Email> not </msg>. Commented Jan 2, 2014 at 9:18
  • Please provide valid xml. Commented Jan 2, 2014 at 9:19
  • it by mistake i update it. Commented Jan 2, 2014 at 9:23

3 Answers 3

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

Sign up to request clarification or add additional context in comments.

Comments

-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>[email protected]</Email>
    </contact>
    <contact>
        <contact_no>9782547000</contact_no>
        <Name>yName</Name>
        <Email>[email protected]</Email>
    </contact>
    <contact>
        <contact_no>9782547012</contact_no>
        <Name>xName</Name>
        <Email>[email protected]</Email>
    </contact>
    <contact>
        <contact_no>9782547011</contact_no>
        <Name>xName</Name>
        <Email>[email protected]</Email>
    </contact>
    <contact>
        <contact_no>9782547012</contact_no>
        <Name>xName</Name>
        <Email>[email protected]</Email>
    </contact>
    <contact>
        <contact_no>9782547000</contact_no>
        <Name>xName</Name>
        <Email>[email protected]</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.

Comments

-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>[email protected]</Email>
  </contact>
   <contact>
    <contact_no>9782547000</contact_no>
    <Name>yName</Name>
    <Email>[email protected]</Email>
  </contact>
   <contact>
    <contact_no>9782547012</contact_no>
    <Name>xName</Name>
    <Email>[email protected]</Email>
  </contact>
   <contact>
    <contact_no>9782547011</contact_no>
    <Name>xName</Name>
    <Email>[email protected]</Email>
  </contact>
   <contact>
    <contact_no>9782547012</contact_no>
    <Name>xName</Name>
    <Email>[email protected]</Email>
  </contact>
   <contact>
    <contact_no>9782547000</contact_no>
    <Name>xName</Name>
    <Email>[email protected]</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.

5 Comments

thanks but i don't want to use array or traverse all tags of file because file may have lacs of records.
why no arrays? btw. @Avi least post the link where u got this code from since this is not your own. stackoverflow.com/questions/9922039/…
@dan if i use array it takes a lot of memory and processing time if my xml file has a large no of records(in lacs)
@Satish Sharma posting another answer under it to your question without the arrays. Please have a look and update me if you have any queries.
Always available for solutions of Problem :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.