Ajay Ajay - 5 months ago 27
PHP Question

PHP + XPath Query get Child Nodes and their values

I have a XML file record.xml which looks like:

<record>
<name>john</name>
<gender>male</gender>
<subject>mathematics, english, science</subject>
</record>
<record>
<name>jamie</name>
<gender>female</gender>
<subject>mathematics, science</subject>
</record>
<record>
<name>jack</name>
<gender>male</gender>
<subject>social-science, english</subject>
</record>


I want to write a xpath query which will return all the child nodeName of
<record>
and value of all these child nodes in an associative array.


For Ex.:

For above XML file Output array should be-

array{
[0] => array{
[name] = 'john',
[gender] = 'male',
[subject] = 'mathematics, english, science'
}
[1] => array{
[name] = 'jamie',
[gender] = 'female',
[subject] = 'mathematics, science'
}
[2] => array{
[name] = 'jack',
[gender] = 'male',
[subject] = 'social-science, english'
}
}



Below is part of Code I written this return all the
<record>
child nodes values but not their node name.

.......
.......
$xmldoc = new DOMDocument();
$xmldoc->load('record.xml');
$xpathvar = new Domxpath($xmldoc);
$res = $xpathvar->query('//record');
foreach($res as $data){
//$data do not contain node values
$arr[] = $data->textContent;
}
//process $arr to get required format
.....
.....


I just want a Xpath query which will return child node names along with their values.

Answer

Problem is a record as a node is just part of the node hierarchy. What you're getting is all records, however you also want to descend and get the data from the record's child nodes. A very case specific example is :

<?php     
$xmldoc = new DOMDocument();
$xmldoc->load('record.xml');
$xpathvar = new Domxpath($xmldoc);
$res = $xpathvar->query('//record');
foreach($res as $data){
    $narr = [];
    foreach ($data->childNodes as $cnode) {
        $narr[$cnode->nodeName] = $cnode->nodeValue;
    }
    $arr[] = $narr;

}    
print_r($arr);

Should output something like:

Array
(
    [0] => Array
        (
            [name] => john
            [gender] => male
            [subject] => mathematics, english, science
        )

    [1] => Array
        (
            [name] => jamie
            [gender] => female
            [subject] => mathematics, science
        )

    [2] => Array
        (
            [name] => jack
            [gender] => male
            [subject] => social-science, english
        )

)

NOTE: This solution is very case specific and would probably break if you have additional nested hierarchies (which I recommend you do in order to store the multiple subjects).