2

I have an XML like

<Person>
  <firstName>pradeep</firstName>
  <lastName>jain</lastName>
  <address>
    <doorNumber>287</doorNumber>
    <street>2nd block</street>
    <city>bangalore</city>
  </address>
  <phoneNums type="mobile">9980572765</phoneNums>
  <phoneNums type="landline">080 42056434</phoneNums>
  <phoneNums type="skype">123456</phoneNums>
</Person>

I want to echo the skype value using php. How do i do it. I wrote code like below but its not working

<?php
$doc = new DOMDocument();

if ($doc->load('new.xml')) 
{
   $userInfo = $doc->getElementsByTagName('Person');

   foreach($userInfo as $row)
   {
       $phoneInfo = $row->getElementsByTagName("phoneNums");

       foreach($phoneInfo as $row2)
       {
            // get the value from the first child
            $work = $row2->getElementsByTagName("mobile")->item(0)->nodeValue;
            $home = $row2->getElementsByTagName("landline")->item(0)->nodeValue;
            echo $work;
       }
   }
}
?>
hakre
  • 193,403
  • 52
  • 435
  • 836
Hacker
  • 7,798
  • 19
  • 84
  • 154
  • What error do you get? At a first glance I can't observe any error. Have you tried for example, BEFORE the first foreach, an echo of count($userinfo)? And if that returns the correct number, then immediately before the second foreach an echo of count($phoneInfo)? So as to have an idea where the problem is. – Soph Jan 02 '12 at 19:17
  • @soph - i get error like Trying to get property of non-object. I am getting the count properly. I get that error at line $work = $row2->getElementsByTagName("mobile")->item(0)->nodeValue; – Hacker Jan 02 '12 at 19:24
  • Ok, and if you try to place an `echo count($phoneInfo)` right before the second foreach? What do you get?? (comment the `foreach` part that comes after) – Soph Jan 02 '12 at 19:56
  • @soph - at both places i get value as 1 – Hacker Jan 02 '12 at 20:09

2 Answers2

3

Sorry for the late reply. I just tried this code based on the XML you posted, with the slight difference that I assumed your XML contains many elements of the tag Person. It is much simpler using SimpleXML as suggested in this question.

<?php
$xml = simplexml_load_file('path\to\doc.xml');
// With the following line you get all the Person tags
$people = $xml->Person;
foreach($people as $person) {
    // For each person you get all the phoneNums tags
    $phoneNumbers = $person->phoneNums;
    foreach($phoneNumbers as $key => $value) {
        $attributes = $value->attributes();
        // We get all of the attributes, and select the one on index 0 -the ONLY attribute in this given case
        if ($attributes[0]=="skype")
            echo $value;
    }
}
?>

This works for an XML like this:

<myXml>
<Person>
  <firstName>pradeep</firstName>
  <lastName>jain</lastName>
  <address>
    <doorNumber>287</doorNumber>
    <street>2nd block</street>
    <city>bangalore</city>
  </address>
  <phoneNums type="mobile">9980572765</phoneNums>
  <phoneNums type="landline">080 42056434</phoneNums>
  <phoneNums type="skype">123456</phoneNums>
</Person>
<Person>
  <firstName>pradeep</firstName>
  <lastName>jain</lastName>
  <address>
    <doorNumber>287</doorNumber>
    <street>2nd block</street>
    <city>bangalore</city>
  </address>
  <phoneNums type="mobile">1</phoneNums>
  <phoneNums type="landline">2</phoneNums>
  <phoneNums type="skype">3</phoneNums>
</Person>
</myXml>

However, if you want to try this with your original XML (with only one person tag), this works:

<?php
// The following loads the ROOT into $xml (in your case, the Person tag is the root)
$xml = simplexml_load_file('path\to\doc.xml');
// Then we get all its children (firstname, lastname, address, etc)
$children = $xml->children();
// Of all its children, we select the phoneNums tags and then iterate
$phoneNumbers = $children->phoneNums;
foreach($phoneNumbers as $key => $value) {
    $attributes = $value->attributes();
    // We get all of the attributes, and select the one on index 0 -the ONLY attribute in this given case
    if ($attributes[0]=="skype")
        echo $value;
}
?>
Community
  • 1
  • 1
Soph
  • 2,895
  • 5
  • 37
  • 68
  • inside the second foreach loop its not printing anything. Can you check the code again once. – Hacker Jan 03 '12 at 03:49
  • @pradeep I showed you the sample XML with which my code worked. I also added the code if you want it to work with the exact XML you posted. The idea of simpleXML is that you can convert XML to an object, and process its elements with normal property selectors and iterators (you can read more about it [here](http://php.net/manual/en/book.simplexml.php)). :) – Soph Jan 03 '12 at 13:01
  • that worked well. But i cant explicitly print the skype number – Hacker Jan 03 '12 at 16:52
  • @pradeep My bad! Forgot you wanted only the skype one. There you go! :D – Soph Jan 03 '12 at 17:16
2

Try using an xpath query:

<?php

$doc = new DOMDocument();

if ($doc->load('xpath.xml')) {

    $xpath = new DOMXPath($doc);
    $query = '/Person/phoneNums[@type="skype"]';
    $results = $xpath->query($query);

    foreach ($results as $result){ // query may have more than one result
        echo $result->nodeValue;
    }

}

?>