2

I'm new to php and coding in general. I'm trying to parse xml from a remote device and access specific value data. I would like to display group 9 probe 1 value for example and I cannot get it to work. Any tips?

Here is the xml:

<?xml version="1.0" encoding="ISO-8859-1" ?> - <Device id="S10011" hb="1935"> <Group id="1" /> <Group id="2" /> <Group id="3" /> <Group id="4" /> <Group id="5" /> <Group id="6" /> <Group id="7" /> <Group id="8" /> - <Group id="9"> - <Probe id="99"> <Value>1.0</Value> </Probe> - <Probe id="1"> <Value>86.4</Value> </Probe> - <Probe id="2"> <Value>45.7</Value> </Probe> - <Probe id="3"> <Value>2.9</Value> </Probe> - <Probe id="4"> <Value>1.0</Value> </Probe> </Group> </Device> 

Here is my php code to read in the xml:

 <?php // Establish a port 80 connection $http = fsockopen("192.168.2.106",80); // Send a request to the server $req = "GET /xmldata HTTP/1.0\r\n"; $req .= "Host: 192.168.2.106\r\n"; $req .= "Connection: Close\r\n\r\n"; fputs($http, $req); // Output the request results while(!feof($http)) { $xmlstr .= fgets($http, 2048); } // Close the connection fclose($http); $xml = simplexml_load_string($xmlstr); print_r($xml); $myValue = $xml->xpath('//Group[@ID="9"]/Probe[@ID="1"]/value'); echo $myValue; ?> 

A print_r($xml); shows the following info:

 SimpleXMLElement Object ( [@attributes] => Array ( [id] => S10011 [hb] => 158221 ) [Group] => Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 1 ) [0] => ) [1] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2 ) [0] => ) [2] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 3 ) [0] => ) [3] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 4 ) [0] => ) [4] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 5 ) [0] => ) [5] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 6 ) [0] => ) [6] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 7 ) [0] => ) [7] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 8 ) [0] => ) [8] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 9 ) [Probe] => Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 99 ) [Value] => 2.0 ) [1] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 1 ) [Value] => 89.6 ) [2] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2 ) [Value] => 42.7 ) [3] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 3 ) [Value] => 3.9 ) [4] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 4 ) [Value] => 1.0 ) ) ) ) ) 
0

4 Answers 4

2

Try this instead:

 $myValue = $xml->xpath('//Group[@id="9"]/Probe[@id="1"]/Value'); echo $myValue[0]; 
Sign up to request clarification or add additional context in comments.

6 Comments

That did it! all I had to do was put the /value at the end of the xpath as well
@Brian Driscoll: /Device/Group[@id="9"]/Probe[@id="1"]/Value would be better. Never start an expression with // operator.
@Alejandro huh? why not?
@Alejandro - your point is valid for large XML docs but for this example I don't see the harm. @Gordon using //FOO will find all nodes that descend from the document root that have the name FOO. In the sample doc this isn't an issue, however in a very large document using that search pattern will cause a performance hit. It would be better to navigate down the hierarchy directly using Alejandro's pattern for larger documents.
@Mike Looking at your code, I still don't understand how that can work. Don't you get an HTTP header when reading the socket? That shouldn't be parsable XML.
|
2

You have to strip the HTTP header from the HTTP response or you won't get a valid XML document. Depending on your hosting environment you may be able to pass an HTTP URL to simplexml_load_file() which is much simpler than what you're doing.

Also your xpath doesn't work because XML attributes and tag names are case sensitive.

$xml = simplexml_load_file("http://192.168.2.106/xmldata"); $myValue = $xml->xpath("//Group[@id='9']/Probe[@id='1']/Value"); echo $myValue[0]; 

Are all these dashes in the XML source just a copy/paste issue?

Comments

0
<?php $device = getDoc(); // iterate over all Group elements that have one or more Probe elements that have one or more Value elements. foreach( $device->xpath('Group[Probe/Value]') as $group ) { echo 'Group id=', $group['id'], "\n"; foreach( $group->Probe as $probe ) { echo ' probe id=', $probe['id'], "\n"; foreach( $probe->Value as $value ) { echo ' value=', $value, "\n"; } } } function getDoc() { return new SimpleXMLElement('<?xml version="1.0" encoding="ISO-8859-1" ?> <Device id="S10011" hb="1935"> <Group id="1" /> <Group id="2" /> <Group id="3" /> <Group id="4" /> <Group id="5" /> <Group id="6" /> <Group id="7" /> <Group id="8" /> <Group id="9"> <Probe id="99"> <Value>1.0</Value> </Probe> <Probe id="1"> <Value>86.4</Value> </Probe> <Probe id="2"> <Value>45.7</Value> </Probe> <Probe id="3"> <Value>2.9</Value> </Probe> <Probe id="4"> <Value>1.0</Value> </Probe> </Group> </Device>'); } 

prints

Group id=9 probe id=99 value=1.0 probe id=1 value=86.4 probe id=2 value=45.7 probe id=3 value=2.9 probe id=4 value=1.0 

see also: http://docs.php.net/simplexml.examples-basic and http://www.w3.org/TR/xpath/

Comments

0

xml:

<root><item attrname="5"/></root> 

php:

$var = $xml->xpath('root/item/@attrname'); echo $var[0]; 

or >= php5.3

$var = $xml->xpath('root/item/@attrname')[0]; echo $var; 

result:

5 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.