0

I have the following XML:

<Root>
    <personalData>
        <userName>John Tom</userName>
        <email>[email protected]</email>
    </personalData>
    <profesionalData>
        <job>engineer</job>
        <jobId>16957</jobId>
    </profesionalData>
</Root>

Doing in my debugger:

$myObject->xpath('//Root/profesionalData')

I have:

: array = 
  0: object(SimpleXMLElement) = 
    job: string = engineer    
    jobId: string = 16957

I cannot get hold of the jobId 16957.

What do I have to do?

1
  • Try $myObject->xpath('//Root/profesionalData')[0]->jobId Commented Dec 7, 2016 at 13:09

1 Answer 1

1
$root = simplexml_load_file('file.xml');


$job_ids = $root->xpath('//profesionalData/jobId');

if (!$job_ids) {
  die("Job IDs not found");
}

foreach ($job_ids as $id) {
  // SimpleXmlElement implements __toString method, so
  // you can fetch the vlaue by casting the object to string.
  $id = (string)$id;
  var_dump($id);
}

Sample Output

string(5) "16957"

Notes

You don't need to specify Root in the XPath expression, if you are going to fetch all profesionalData/jobId tags no matter where they are in the document, just use the double slash (//) expression. This approach may be convenient in cases, when you want to avoid registering the XML namespaces. Otherwise, you can use a strict expression like /Root/profesionalData/jobId (path from the root). By the way, your current expression (//Root/profesionalData/jobId) matches all occurrences of /Root/profesionalData/jobId in the document, e.g. /x/y/z/Root/profesionalData/jobId.

Since SimpleXmlElement::xpath function returns an array on success, or FALSE on failure, you should iterate the value with a loop, if it is a non-empty array.

SimpleXmlElement implements __toString method. The method is called when the object appears in a string context. In particular, you can cast the object to string in order to fetch string content of the node.

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

2 Comments

Er.. This will always fail because of your if!
The first note is wrong. // does not point to the 'Root' element but it is a reference to its parent node (in this case). A / at the start of an location path points to the document itself, // is the descendant axis. So //Root/profesionalData will look for any profesionalData element node that is a direct child of an Root element node.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.