1

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

Kevin
  • 41,694
  • 12
  • 53
  • 70

3 Answers3

1

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"
ThW
  • 19,120
  • 3
  • 22
  • 44
0

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

Kevin
  • 41,694
  • 12
  • 53
  • 70
0

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 />";
}