We need to update a somewhat old API a customer is using. We're getting the data with simplexml_load_file. The new structure is a bit more complex and I could not find a way to retrieve the new data.
The new structure looks like this:
Before we used $ratingPrice = $xml->hotel->ratingPrice; to get a value.
Now, I need to retrieve $xml->business->subcategoryRating->subcategoryRating->averageRating. I'm now stuck with that.
How am I able to get the average rating of wifi, or location and have them outputted in single variables?
If the order of your information is always the same (eg. Wi-Fi, Location, Apartment, Cleanliness) then you can do
$xml->business->subcategoryRating->subcategoryRating[x]->averageRating
so the x is the index of your xml list. Then
...subcategoryRating[0]->averageRating
corresponds to Wi-Fi and
...subcategoryRating[1]->averageRating
corresponds to Location and so forth.
You can extract the various ratings into an array and then use the relevant index to process the data your after. This uses the id attribute of the (for example) <category id="location"> element to use as the index...
$ratings = [];
foreach ( $xml->business->subcategoryRatings->subcategoryRating as $rating ) {
$ratings[(string)$rating->category['id']] = (string)$rating->averageRating;
}
echo $ratings["location"].PHP_EOL;
This last line will need to be updated to access the particular element your after.
As an alternative you could create an xpath expression and use xpath.
That would give you array of SimpleXMLElement objects.
$xml = simplexml_load_string($data);
$expression = '//business/subcategoryRatings/subcategoryRating[category[#id="wifi" or #id="location"]]';
foreach($xml->xpath($expression) as $item) {
$averageRating = (string)$item->averageRating;
}
Related
Sorry to be asking this, but it's driving me crazy.
I've been using the php SimpleXMLElement as my XML go to parser, and I've looked at many examples, and have given up on this many times. But, now, I just need to have this working. There are many examples on how to get simple fields, but not so many with values in the fields...
I'm trying to get the "track_artist_name" value from this XML as a named variable in php.
<nowplaying-info-list>
<nowplaying-info >
<property name="track_title"><![CDATA[Song Title]]></property>
<property name="track_album_name"><![CDATA[Song Album]]></property>
<property name="track_artist_name"><![CDATA[Song Artist]]></property>
</nowplaying-info>
</nowplaying-info-list>
I've tried using xpath with:
$sxml->xpath("/nowplaying-info-list[0]/nowplaying-info/property[#name='track_artist_name']"));
But, I know it's all mucked up and not working.
I originally tried something like this too, thinking it made sense - but no:
attrs = $sxml->nowplaying_info[0]->property['#name']['track_artist_name'];
echo $attrs . "\n\n";
I know I can get the values with something such as this:
$sxml->nowplaying_info[0]->property[2];
Sometimes there are more lines in the XML results than other times, and so because of this, it is breaks the calculations with the wrong data.
Can someone shed some light on my problem? I'm just trying to the name of the artist to a variable. Many thanks.
*** WORKING UPDATE: **
I was unaware there were different XML interpreter methods, and was using the following XML interpreter version:
// read feed into SimpleXML object
$sxml = new SimpleXMLElement($json);
That didn't work, but have now updated to the following (for that section of code) thanks to the help here.
$sxml_new = simplexml_load_string($json_raw);
if ( $sxml_new->xpath("/nowplaying-info-list/nowplaying-info/property[#name='track_artist_name']") != null )
{
$results = $sxml_new->xpath("/nowplaying-info-list/nowplaying-info/property[#name='track_artist_name']");
//print_r($results);
$artist = (string) $results[0];
// var_dump($artist);
echo "Artist: " . $artist . "\n";
}
Your xpath expression is pretty much right, but you don't need to specify an index for the <nowplaying-info-list> element - it'll deal with that itself. If you were to supply an index, it would need to start at 1, not 0.
Try
$results = $sxml->xpath("/nowplaying-info-list/nowplaying-info/property[#name='track_artist_name']");
echo (string) $results[0];
Song Artist
See https://3v4l.org/eH4Dr
Your second approach:
$sxml->nowplaying_info[0]->property['#name']['track_artist_name'];
Would be trying to access the attribute named #name of the first property element, rather than treating it as an xpath-style # expression. To do this without using xpath, you'd need to loop over each of the <property> elements, and test their name attibrute.
Just in case if the node you are looking for is deeply residing some where, you could just add a double slash at the start.
$results = $sxml->xpath("//nowplaying-info-list/nowplaying-info/property[#name='track_artist_name']");
Also in case if you have multiple <nowplaying-info> elements. You could make of use of the index for that. (note the [1] index)
$results = $sxml->xpath("//nowplaying-info-list/nowplaying-info[1]/property[#name='track_artist_name']");
Till now I was using PHP Rest Api in order to send requests with cypher queries and get a response back. The response is a huge string which makes it difficult to parse and can not be transformed to JSON.
I now installed Neo4jPHP and I am trying to figure out how to write the same query I had in cypher.
This is my query:
MATCH (n:RealNode)-[r:contains*]-(z) WHERE n.gid='123' RETURN n,z;")
What I actually want is to get a list of all the names of the nodes (name is a property inside each node) which is related to my n node. How do I do this?
I can not find many examples for Neo4jPHP onnline and the ones I found seem not to work. I downloaded the latest version from here (https://github.com/jadell/neo4jphp).
Thanks
D.
RE-EDITED
I try this query in neo4j Server:
MATCH (n)-[r:KNOWS*]-(z) WHERE n.name='Arthur Dent' AND z.name='Ford Prefect' RETURN n,z,r;
and I get all the 3 nodes which are connected to each other. The same query through neo4jPHP will return only the name of one node. Why is this happening?
$querystring="MATCH path=(n:RealNode {gid:'58731'})-[:contains*]-(z) RETURN [x in nodes(path) | x.id] as names";
$query=new Everyman\Neo4j\Cypher\Query($client,$querystring);
$result=$query->getResultSet();
print_r($result);
foreach($result as $row){
echo $row['x']->getProperty('name') . "\n";
}
On Cypher level you might use a query like:
MATCH path=(n {name:'Arthur Dent'])-[:KNOWS*]-(z {name:'Ford Perfect'})
RETURN [x in nodes(path) | x.name] as names
You assign a variable to a pattern, here path. In the RETURN you iterate over all nodes along that path and extract its name property.
2 additional hints:
consider assigning labels e.g. Person to your nodes and use a declarative index ( CREATE INDEX ON :Person(name) ) to speed up the look up for start/end node of your query
for variable path length matches [:KNOWS*] consider using an upper limit, depending on the size and structure of your graph this can get rather expensive. [:KNOWS*10] to limit on 10th degree.
After lots of trying and some help from Stefan Armbruster I made it work using Neo4jPHP.
This is how it looks:
$client = new Everyman\Neo4j\Client();
$querystring="MATCH path=(n {gid:'58731'})-[:contains*]-(z) RETURN LAST([x in nodes(path) | x.id]) as names";
$query=new Everyman\Neo4j\Cypher\Query($client,$querystring);
$result=$query->getResultSet();
foreach($result as $resultItem){
$resultArray[] = $resultItem['n'];
}
print_r($resultArray); // prints the array
Neo4jPHP is very handy tool but not very popular. Small community and few examples online. Hope this helps someone.
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);
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;
}
?>
I'm trying to parse this feed: http://musicbrainz.org/ws/1/artist/c0b2500e-0cef-4130-869d-732b23ed9df5?type=xml&inc=url-rels
I want to grab the URLs inside the 'relation-list' tag.
I've tried fetching the URL with PHP using simplexml_load_file(), but I can't access it using $feed->artist->relation-list as PHP interprets "list" as the list() function.
I have a feeling I'm going about this wrong (not much XML experience), and even if I was able to get hold of the elements I want, I don't know how to extract their attributes (I just want the type and target fields).
Can anyone gently nudge me in the right direction?
Thanks.
Matt
Have a look at the examples on the php.net page, they actually tell you how to solve this:
// $feed->artist->relation-list
$feed->artist->{'relation-list'}
To get an attribute of a node, just use the attribute name as array index on the node:
foreach( $feed->artist->{'relation-list'}->relation as $relation ) {
$target = (string)$relation['target'];
$type = (string)$relation['type'];
// Do something with it
}
(Untested)