Using PHP SimpleXML to parse an oBix XML feed? - php

I am rather new to development, but a long time sys-admin. I am trying to retrieve a specific value from the following XML feed. (Its oBix).
http://80.68.58.47:900/obix/config/Drivers/NiagaraNetwork/OSS_Tridium_Demo/points/kW_Sys/
I am trying to return the "Out" value within the 'Real' element (If element is the right name for it). The value is a number next to val=.
I have spent a fair few hours trying to work out how to isolate the 'val' attribute and return the number but I can't seem to do it. I can isolate the 'real' element but can't go any further in to get the actual number value.
Could someone show me how this is done using PHP SimpleXML so I can try to get my head round it?
This is my code so far:
<?php
$url = "http://80.68.58.47:900/obix/config/Drivers/NiagaraNetwork/OSS_Tridium_Demo/points/kW_Sys/";
$xml = simplexml_load_file($url);
$elementselection = $xml->real[0];
$outputvalue = $elementselection;
print_r ($outputvalue);
?>
Many Thanks!
Tom

If you just want the value from the first 'real' element you can use the following:
$url = "http://80.68.58.47:900/obix/config/Drivers/NiagaraNetwork/OSS_Tridium_Demo/points/kW_Sys/";
$xml = simplexml_load_file($url);
$value = (string) $xml->real[0]['val'];
var_dump($value);

Related

Parsing deep XML with PHP SimpleXML and XPath

PHP noob here. I seem to be misunderstanding how to get the value of an XML node using XPath, and I haven't been able to find a StackOverflow answer that quite address what I'm doing wrong.
So, using RPG Geek's API, I'm trying to pull some information about the game Dread. (Here's a link to the URI.)
$rpggeekXML = simplexml_load_file('https://www.rpggeek.com/xmlapi/boardgame/166952?&stats=1');
$rating = $rpggeekXML->xpath('ratings/average');
$usersrated = $rpggeekXML->xpath('ratings/usersrated');
I know I'm successfully pulling in the rpggeek XML because if I do var_dump($rpggeekXML);, I can see all of the information I'm expecting. However, if I do var_dump($rating); or var_dump($usersrated);, it returns array(0) { }. So it seems I must be screwing up the XPath lines, but I can't figure out how. What am I doing wrong?
Use full path to find desired node:
$rating = $rpggeekXML->xpath( 'boardgame/statistics/ratings/average' );
echo $rating[0];
Collect all "average" nodes in document:
$rating = $rpggeekXML->xpath( '//average' );
echo $rating[0];
I think you xpath syntax is wrong. You can try this
$rpggeekXML = simplexml_load_file('https://www.rpggeek.com/xmlapi/boardgame/166952?&stats=1');
$rating = $rpggeekXML->xpath('//ratings/average');
$usersrated = $rpggeekXML->xpath('//ratings/usersrated');

Simple use PHP to get data from XML

I am getting some variable where is XML file, I can't edit it or do anything with it.
So what I do:
$xml = $client->get_details('WF0GXXGBBG7P857BB');
$xml = simplexml_load_string($xml);
//print_r($xml);
$vin = $xml->vin;
print_r($vin);
If I uncomment print_r($xml) it just prints out whole xml and works cool (output is http://pastebin.com/w5VVysZU), but if I use second part with print_r($vin) it just displays just SimpleXMLElement Object ( ),
Any idea what can I do? How can I fix this? I've tried like 20 tutorials and always get no output or error with using nonobject something.
EDIT 1:
I need it to display one specific thing from this XML, in example it's VIN, so from this big amount I want script to find where is [vin] => WF0GXXGBBG7P857BB and echo WF0GXXGBBG7P857BB
EDIT 2:
My XML: http://pastebin.com/1KLB5Ba0
SimpleXML elements can and have to be type casted to strings if you want to display them that way. Otherwise, as you seen, it just tells you that it is an object.
$vin = (string) $xml->vin;
// OR
print_r((string) $vin);

Create comma separated string via xml values

I'm working on some system for a few hours now and this little thing is too much for me to think logically about at the moment.
Normally I would wait a few hours but this is a last minute job and I need to finish this.
Here's my problem:
I have an XML file that gets posted to my PHP file, the PHP file inserts certain data into a DB, but some XML nodes have the same name:
<accessoires>
<accessoire>value1</accessoire>
<accessoire>value2</accessoire>
<accessoire>value3</accessoire>
</accessoires>
Now I want to get a var $acclist which contains all values seperated by a comma:
value1,value2,value3,
I bet the solution to this is very easy but I'm at the known point where even the easiest piece of code becomes a hassle. And googling only comes up with nodes that in some way have their own identifiers.
Could someone help me out please?
You can try simplexml_load_string to parse the html then call implode on the node after casting to an array.
NOTE This code was tested in php 5.4.6 and behaves as expected.
<?php
$xml = '<accessoires>
<accessoire>value1</accessoire>
<accessoire>value2</accessoire>
<accessoire>value3</accessoire>
</accessoires>';
$dat = simplexml_load_string($xml);
echo implode(",",(array)$dat->accessoire);
For 5.3.x I had to change to
$xml = '<accessoires>
<accessoire>value1</accessoire>
<accessoire>value2</accessoire>
<accessoire>value3</accessoire>
</accessoires>';
$dat = simplexml_load_string($xml);
$dat = (array)$dat;
echo implode(",",$dat["accessoire"]);
You do this by taking a library that is able to parse and process XML, for example with SimpleXML:
implode(',', iterator_to_array($accessoires->accessoire, FALSE));
The key part here is to use iterator_to_array() as SimpleXML offers the same-named child-elements here as an iterator. Otherwise $accessoires->accessoire gives you auto-magically only the first element (if any).

Why isn't PHP continuing to run through these urls?

I have the following PHP. Basically, I'm getting similar data from multiple pages of a website (the current number of homeruns from a website that has a bunch of baseball player profiles). The JSON that I'm bringing in has all of the URLs to all of the different profiles that I'm looking to grab from, and so I need PHP to run through the URLs and grab the data. However, the following PHP only gets the info from the very first URL. I'm probably making a stupid mistake. Can anyone see why it's not going through all the URLs?
include('simple_html_dom.php');
$json = file_get_contents("http://example.com/homeruns.json");
$elements = json_decode($json);
foreach ($elements as $element){
$html = new simple_html_dom();
$html->load_file($element->profileurl);
$currenthomeruns = $html->find('.homeruns .current',0);
echo $element->name, " currently has the following number of homeruns: ", strip_tags($currenthomeruns);
return $html;
}
Wait... You are using return $html. Why? Return is going to break out of your function, thus stopping your foreach.
If you are indeed trying to get the $html out of your function for ALL of the elements, you should push each $html into an array and then return that array after the loop.
Because you return. return leaves the current method, function, or script, which includes every loop. With PHP5.5 you can use yield to let the function behaves like an generator, but this is definitely out of scope for now.
Unless your braces are off, you return at the very end of the loop so the loop will never iterate.

Find a node with xpath

I'd like to parse google geocode api respond, but the structure of the result is not always the same. I need to know the postal code for example, but it is sometimes in the Locality/DependentLocality/PostalCode/PostalCodeNumber node and sometimes in the Locality/PostalCode/PostalCodeNumber node. I don't really know the logic behind this, just want to get the value of the PostalCodeNumber node, no matter where is it exactly. Can I do it with XPath? If so, how?
UPDATE
Tried with //PostalCodeNumber but it returns an empty array. The code snippet is the following:
$xml = new \SimpleXMLElement($response);
var_dump($xml->xpath('//PostalCodeNumber'));
The $response is the content of http://maps.google.com/maps/geo?q=1055+Budapest&output=xml
(copy paste the url instead of clicking on it because of some character problems...)
Try to use this XPath:
Locality//PostalCodeNumber
It will find all descendants PostalCodeNumber of Locality element.
//PostalCode/PostalCodeNumber
Should do the trick. A quick google search yields the following schema snippet, indicating that there may be multiple DependentLocality elements, nested, so you'll want to check for multiple results, and have some idea of whether you want the most specific (most deeply nested) or least specific.
Update:
To guard against namespace issues, explicitly add the namespace to the query:
$xml = new SimpleXMLElement($response);
$xpath->registerXPathNamespace('ns', 'urn:oasis:names:tc:ciq:xsdschema:xAL:2.0');
var_dump($xml->xpath('//ns:PostalCodeNumber'));
Update 2: fixed a couple of typos
Update 3:
<?php
$result = file_get_contents('http://maps.google.com/maps/geo?q=1055+Budapest&output=xml');
$sxe = new SimpleXMLElement($result);
$sxe->registerXPathNamespace('c', 'urn:oasis:names:tc:ciq:xsdschema:xAL:2.0');
$search = $sxe->xpath('//c:PostalCodeNumber');
foreach($search as $code) {
echo $code;
}
?>

Categories