Bhavin Toliya
Bhavin Toliya

Reputation: 17

how to select nodevalue based on another nodevalue via php ?

I have a xml file which contains this :

<ns1:Response xmlns:ns1="http://example.com/">
- <ns1:return>
   <ns1:mid>39824</ns1:mid> 
   <ns1:serverType>4</ns1:serverType> 
   <ns1:size>5</ns1:size> 
 </ns1:return>
- <ns1:return>....
</ns1:return>

Now I want to get nodevalue of mid where nodevalue size has 5, I tried following code but no results:

$doc = new DOMDocument();
$doc->load($file);

$xpath = new DOMXPath($doc);

$query = '//Response/return/size[.="5"]/mid';

$entries = $xpath->evaluate($query);

So how can I do that ?

thanks in advance

Upvotes: 1

Views: 83

Answers (3)

ThW
ThW

Reputation: 19512

PHP has some automatic registration for the namespaces of the current context, but it is a better idea not to depend on it. Prefixes can change. You can even use a default namespace and avoid the prefixes.

Best register your own prefix:

$xpath->registerNamespace('e', 'http://example.com/');

In XPath you define location paths with conditions:

Any return node inside a Response node:

//e:Response/e:return

If it has a child node size node with the value 5

//e:Response/e:return[e:size = 5]

Get the mid node inside it

//e:Response/e:return[e:size = 5]/e:mid

Cast the first found mid node into a string

string(//e:Response/e:return[e:size = 5]/e:mid)

Complete example:

$xml = <<<'XML'
<ns1:Response xmlns:ns1="http://example.com/">
 <ns1:return>
   <ns1:mid>39824</ns1:mid> 
   <ns1:serverType>4</ns1:serverType> 
   <ns1:size>5</ns1:size> 
 </ns1:return>
 <ns1:return></ns1:return>
</ns1:Response>
XML;

$doc = new DOMDocument();
$doc->loadXml($xml);

$xpath = new DOMXPath($doc);
$xpath->registerNamespace('e', 'http://example.com/');

$mid = $xpath->evaluate(
  'string(//e:Response/e:return[e:size = 5]/e:mid)'
);
var_dump($mid);

Output:

string(5) "39824"

Upvotes: 1

Nicola Pulvirenti
Nicola Pulvirenti

Reputation: 29

You're missing some namespace and you're trying to get the child mid of a size element whose content is 5.

try this:

$query = '//ns1:Response/ns1:return/ns1:mid[../ns1:size[text()="5"]]';

then, to see the result:

foreach ($entries as $entry) {
    echo $entry->nodeValue . "<br />";
}

Upvotes: 0

Kevin
Kevin

Reputation: 41903

You can also use following::sibling in this case. Get mid value where its following sibling is size with text equal to 5. Rough example:

$query = 'string(//ns1:Response/ns1:return/ns1:mid[following-sibling::ns1:size[text()="5"]])';

Sample Output

Upvotes: 0

Related Questions