XML multidimentional array php from URL [duplicate] - php

This question already has answers here:
SimpleXML: Working with XML containing namespaces
(3 answers)
Closed 7 years ago.
I'm breaking my head about this one for 2 days now, so I hope someone can help a bit.
I need the data from an XML, which I get from a website. The code returns a nice list, but missing the time array (array from an array).
Here is my code :
<?php
$url="http://publications.elia.be/Publications/Publications/WindForecasting.v1.svc/GetForecastGraphDataXml?beginDate=2015-05-13&endDate=2015-05-18&isOffshore=&isEliaConnected=";
echo $url;
$sxml = Simplexml_load_file($url);
var_dump($sxml);
foreach ($sxml ->ForecastGraphItems ->WindForecastingGraphItem as $type){
echo 'FC ';
echo $type ->Forecast."<br>";
echo 'LF ';
echo $type ->LoadFactor."<br>";
echo 'DT ';
echo $type ->Time[0]->DateTime;
echo "<br>";
echo 'BID ';
echo $type ->Bid."<br>";
echo 'RA ';
echo $type ->RunningAverage."<br>";
echo "<br>";
}
?>
The XML format I get when I just manualy open the website looks like the code below, or check the Original website : http://publications.elia.be/Publications/Publications/WindForecasting.v1.svc/GetForecastGraphDataXml?beginDate=2015-05-13&endDate=2015-05-18&isOffshore=&isEliaConnected=
<?xml version="1.0" encoding="UTF-8"?>
<WindForecastingGraphDataResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Elia.PublicationService.DomainInterface.WindForecasting.v1">
<ErrorMessage i:nil="true"/>
<ForecastGraphItems>
<WindForecastingGraphItem>
<Bid>No</Bid>
<Forecast>571.45</Forecast>
<LoadFactor>0.32</LoadFactor>
<RunningAverage>585.59</RunningAverage>
<Time xmlns:a="http://schemas.datacontract.org/2004/07/System">
<a:DateTime>2015-05-12T22:00:00Z</a:DateTime>
<a:OffsetMinutes>120</a:OffsetMinutes>
</Time>
</WindForecastingGraphItem>
<WindForecastingGraphItem>
<Bid>No</Bid>
<Forecast>562.95</Forecast>
<LoadFactor>0.32</LoadFactor>
<RunningAverage>578.47</RunningAverage>
<Time xmlns:a="http://schemas.datacontract.org/2004/07/System">
<a:DateTime>2015-05-12T22:15:00Z</a:DateTime>
<a:OffsetMinutes>120</a:OffsetMinutes>
</Time>
Now, when I var_dump($sxml), or if I try to get it, the sub-array for TIME dropped out... (see below).
I also tried foreach ($sxml ->ForecastGraphItems ->WindForecastingGraphItem -> Time as $time){ ..., which worked, but returned empty.
Anyone can help why the 'time' array is empty ?
Below the echo for var_dump:
http://publications.elia.be/Publications/Publications/WindForecasting.v1.svc/GetForecastGraphDataXml?beginDate=2015-05-13&endDate=2015-05-18&isOffshore=&isEliaConnected=object(SimpleXMLElement)#1
(2) { ["ErrorMessage"]=> object(SimpleXMLElement)#2 (0) { }
["ForecastGraphItems"]=> object(SimpleXMLElement)#3 (1) {
["WindForecastingGraphItem"]=> array(481) { [0]=>
object(SimpleXMLElement)#4 (5) { ["Bid"]=> string(2) "No"
["Forecast"]=> string(6) "571.45" ["LoadFactor"]=> string(4) "0.32"
["RunningAverage"]=> string(6) "585.59" ["Time"]=>
object(SimpleXMLElement)#485 (0) { } } [1]=>
object(SimpleXMLElement)#5 (5) { ["Bid"]=> string(2) "No"
["Forecast"]=> string(6) "562.95" ["LoadFactor"]=> string(4) "0.32"
["RunningAverage"]=> string(6) "578.47" ["Time"]=>
object(SimpleXMLElement)#485 (0) { } }

As michi has commented already you'd like to get access to elements that are in a different namespace:
<Time xmlns:a="http://schemas.datacontract.org/2004/07/System">
<a:DateTime>2015-05-12T22:15:00Z</a:DateTime>
<a:OffsetMinutes>120</a:OffsetMinutes>
</Time>
The <Time> element sets for all it's children the prefix a to the XML namespace http://schemas.datacontract.org/2004/07/System. You're interested in two children with that prefix:
<a:DateTime>2015-05-12T22:15:00Z</a:DateTime>
<a:OffsetMinutes>120</a:OffsetMinutes>
You do this by telling the namespace of the children you're interested in, e.g. for the first element:
$type ->Time->children('http://schemas.datacontract.org/2004/07/System')->DateTime;
And that's it already.
Now to correct some misunderstanding:
that is not an array
yes, var_dump told you it's one, but it's just not.
var_dump and print_r are not particular useful with SimpleXMLElement as they lie about it. SimpleXMLElement::asXML() shows you the concrete XML, always.

Related

php simplexml node no longer exists : how to get attribute value?

After wasting more than 6 hour, I'm posting my problem here.
I'm trying to get simplexmlelement attribute value :
This is my var_dump value :
object(SimpleXMLElement)#5 (1) {
["#attributes"]=>
array(3) {
["type"]=>
string(4) "Rich"
["template"]=>
string(44) "EntityContainer.HeroGeneric_8_1_RTM-7814aaaa"
["disambiguationId"]=>
string(36) "85fa63d3-9596-adb9-b4eb-502273d84f56"
}
}
I want to get ["type"] value "Rich". However i am not able to get that. I've seen a lot of answers and code example before post it here but they did not help.
Actually first time i am trying to use simplexmlelement [Advance code]
My php code
$xml = simplexml_load_file($url);
$xml2 = $xml->channel->item;
foreach ($xml2 as $out_ns)
{
$ns = $out_ns->getNamespaces(true);
$child = $out_ns->children($ns['win']);
var_dump($child); // Value is written above simple xml object
print_r((string) $child->attributes());
}
I want to know what's wrong i have done. I want to achieve type and disambiguationId attribute values.
Error:
Warning: SimpleXMLElement::__toString(): Node no longer exists in E:\xampp\htdocs\ring\dom.php on line 15
Please check my code help me.
You have to check if element exists:
if($child && $child->attributes()) {
print_r($child->attributes());
}

Get Value From JSON decode in PHP [duplicate]

This question already has answers here:
How to loop through an array of objects that have been decoded from JSON in PHP, and echo the values
(6 answers)
Closed 7 years ago.
I have tried but still not working fine. I have one array that i get from JSON decode in PHP file, I use Ajax for send this array from javascript, this is how i get array.
$q = json_decode($_GET['q'], true);
I do var_dump this variable and this is the result:
array(2)
{ [0]=> array(1)
{ ["data"]=> array(2)
{ ["Text1"]=> string(1) "Car 1" ["Text2"]=> string(1) "Car 2" }
}
[1]=> array(1)
{ ["data"]=> array(2)
{ ["Text1"]=> string(1) "Car 3" ["Text2"]=> string(1) "Car 4" }
}
}
My question is, how do i get value like "Car 1" or "Car 2" etc from this array? this array like 2 dimensional array, i difficult to get this value. i have found many post related it, i try, but still not solved. Really need help please..
try this,
foreach($pass_your_array as $ta)
{
if(isset($ta['data']))
{
foreach ($ta['data'] as $text)
{
$txt1 = $text['Text1']; // gives car1
$txt2 = $text['Text2']; // gives car2
}
}
}

Accessing a specific XML-node with PHP using SimpleXML

lately i ran into a problem using simplexml.
What i want to do is to get a value of a nested node that occurs multiple times.
The xml looks somewhat like this:
<response>
<album id="123">
[...]
<duration>
<value format="seconds">2576</value>
<value format="mm:ss">42:56</value>
<value format="hh:mm:ss">00:42:56</value>
<value format="xs:duration">PT42M56S</value>
</duration>
[...]
</album>
</response>
Specifically i need the value of the the <value format="hh:mm:ss"> node.
So I have a reference to the object that looks somewhat like this:
$this->webservice->album->duration->value;
Now, if i var_dump this the result will be:
object(SimpleXMLElement)#117 (5) {
["#attributes"]=> array(1) {
["format"]=> string(7) "seconds"
}
[0]=> string(4) "2576"
[1]=> string(5) "42:56"
[2]=> string(8) "00:42:56"
[3]=> string(8) "PT42M56S"
}
I do not understand this output, since it takes the format-attribute of the first node (seconds) and continues with the node-values in the array, while ignoring the format-attribute of the following nodes completely.
Furthermore, if i do the following:
$this->webservice->album->duration->value[2];
it results in:
object(SimpleXMLElement)#108 (1) {
["#attributes"]=> array(1) {
["format"]=> string(8) "hh:mm:ss"
}
}
where i haven't got a value to address at all.
I tried to use xpath instead too in the following way:
$this->webservice->album->duration->xpath('value[#format="hh:mm:ss"]');
which results in:
array(1) {
[0]=> object(SimpleXMLElement)#116 (1) {
["#attributes"]=> array(1) {
["format"]=> string(8) "hh:mm:ss"
}
}
}
So my question is:
What am I doing wrong? xD
Thanks in advance for any helpful advice :)
Your mistake is in trusting var_dump too completely, rather than trying to use the elements based on the examples in the manual.
On your first attempt, you accessed $duration_node->value; this can be used in a few different ways:
if you iterate over it with foreach($duration_node->value as $value_node), you get each of the <value> elements in turn
you can access specific elements by index, e.g. $duration_node->value[2] for the 3rd element
if you treat it as a single element, SimpleXML assumes you want the first element, i.e. echo $duration_node->value is the same as echo $duration_node->value[0]
Your second example worked fine - it found the <value> element with an attribute format="hh:mm:ss". The xpath() method always returns an array, so you need to check that it's not empty then look at the first element.
Once you have the right element, accessing its text content is as simple as casting it to a string ((string)$foo), or passing it to something that always needs a string (e.g. echo).
So this would work:
$xpath_results = $this->webservice->album->duration->xpath('value[#format="hh:mm:ss"]');
if ( count($xpath_results) != 0 ) {
$value = (string)$xpath_results[0];
}
As would this:
foreach ( $this->webservice->album->duration->value as $value_node ) {
if ( $value_node['format'] == 'hh:mm:ss' ) {
$value = (string)$value_node;
break;
}
}

Accessing CDATA values in a simplexmliterator

I have a simple xml structure:
<?xml version="1.0"?>
<fmxmlsnippet type="FMObjectList">
<Step enable="True" id="141" name="Set Variable">
<Value>
<Calculation><![CDATA[Get(RecordID)]]></Calculation>
</Value>
<Repetition>
<Calculation><![CDATA[1]]></Calculation>
</Repetition>
<Name>$currentRecord</Name>
</Step>
</fmxmlsnippet>
What I'm trying to do is pull out the attribute values for the Step node as well as the CDATA values form the Calculation child node for the Value and Repetition nodes.
I can get the step attribute values without an issue:
$iterator = new SimpleXMLIterator($xml);
for($iterator->rewind() ; $iterator->valid() ; $iterator->next()){
$stepId = $iterator->current()->attributes()->id->__toString();
$stepName = $iterator->current()->attributes()->name->__toString();
$stepEnable= $iterator->current()->attributes()->enable->__toString();
}
But I'm having a problem getting the CDATA. I've tried numerous methods of getting it without success.
I noticed at one point that when I die and var_dump the result of $iterator->current() in my for loop the CDATA doesn't even look like it is recognized:
object(SimpleXMLIterator)#3 (4) {
["#attributes"]=>
array(3) {
["enable"]=>
string(4) "True"
["id"]=>
string(3) "141"
["name"]=>
string(12) "Set Variable"
}
["Value"]=>
object(SimpleXMLIterator)#4 (1) {
["Calculation"]=>
object(SimpleXMLIterator)#6 (0) {
}
}
["Repetition"]=>
object(SimpleXMLIterator)#5 (1) {
["Calculation"]=>
object(SimpleXMLIterator)#6 (0) {
}
}
["Name"]=>
string(14) "$currentRecord"
}
It's like the content of the Calculation nodes is empty.
Is there a way of getting the CDATA?
No, that var_dump() is just misleading, it shows its empty but its it is there. Simply cast it then assign:
for($iterator->rewind() ; $iterator->valid() ; $iterator->next()){
$stepId = $iterator->current()->attributes()->id->__toString();
$stepName = $iterator->current()->attributes()->name->__toString();
$stepEnable= $iterator->current()->attributes()->enable->__toString();
$calculation = (string) $iterator->current()->Value->Calculation;
$repitition = (string) $iterator->current()->Repetition->Calculation;
echo $calculation . '<br/>' . $repitition;
}
Sample Output

Foreach through an array with objects and return the values and keys

array(14) {
[0]=>
object(stdClass)#2 (2) {
["set_id"]=>
int(44)
["name"]=>
string(7) "Cameras"
}
[1]=>
object(stdClass)#3 (2) {
["set_id"]=>
int(38)
["name"]=>
string(11) "Cell Phones"
}
[2]=>
object(stdClass)#4 (2) {
["set_id"]=>
int(39)
["name"]=>
string(8) "Computer"
}
The Above is my Data.
I want to return the object names ["Set_ID"] etc and the value.
I have googled and googled and tried examples from here with various failures and now I'm giving up.
I have tried to simply manually return data - ie
foreach($result as $results2)
{
foreach($results2->name as $item)
{
echo "<pre>";
print_r($item);
echo "</pre>";
}
}
I have tried all sorts of flavors of it I had kind of hoped the above would at least return data and it didn't - just errored.
In the end, I'd like to be able to both pull names and data. I don't want to have to manually find element names and code it as $result->SET_ID or whatever - I want to be able to just feed SET_ID in as a variable. I think my problem lies with it being an array of objects and I cant access that object name and all..
Im a noob, so any kind of like detailed explanation wouldn't hurt my feelings so I can learn something.
Instead of foreach($results2->name as $item) use foreach($results2 as $item). $results2->name is not an array thus causing the error.
You can read about object iteration in PHP here
foreach($result as $results2)
{
echo $results2->name.' '.$results2->set_id;
}

Categories