Trying to get property of non-object SimpleXML? - php

I am currently using the following code to retrieve information from a REST api.
$url = "http://api.remix.bestbuy.com/v1/products%28upc=".$upc."%29?apiKey=(API KEY)";
$xmlfiledata = file_get_contents("$url");
$xmldata = new SimpleXMLElement($xmlfiledata);
$saleprice = $xmldata->products->product->salePrice;
echo $saleprice;
However, PHP is returning this error.
Notice: Trying to get property of non-object in FILE LOCATION on line 132
line 132 is:
$saleprice = $xmldata->products->product->salePrice;
I have verified that the URL being produced is correct. The xml document in question is here (I simplified it for the sake of simplicity).
<products currentPage="1" totalPages="1" from="1" to="1" total="1" queryTime="0.006" totalTime="0.014" canonicalUrl="/v1/products(upc="635753489873")?apiKey=xr2r8us3dcef7qdjnecbvh6g" partial="false">
<product>
<salePrice>529.99</salePrice>
</product>
</products>
How to fix?

Looking at the examples on PHP.net, I believe you'd need to do the access like this:
$saleprice = $xmldata->product[0]->salePrice;
$xmldata is actually your "products" level, so I don't think you need ...->products->...

Related

Simplexml_load_file is working with one example, but not with other one

I made a simple website to show actually currency rates from bank website, here is xml from I got these data: http://www.nbp.pl/kursy/xml/LastA.xml. I put this into a code like that:
$xml = simplexml_load_file('http://www.nbp.pl/kursy/xml/LastA.xml');
and get it to variables like that:
<?php
for($i=0; $i<35; $i++){
$rate = (string)$xml->pozycja[$i]->kurs_sredni;
$name = (string)$xml->pozycja[$i]->nazwa_waluty;
$code = (string)$xml->pozycja[$i]->kod_waluty;
(echo here)
It works. But if I'd like to get this data from this xml, for example from yesterday: http://api.nbp.pl/api/exchangerates/tables/a/2017-04-05?format=xml, and do the same I have only errors:
Warning: simplexml_load_file(): http://api.nbp.pl/api/exchangerates/tables/a/2017-04-05:1: parser error : Start tag expected, '<' not found in [PATH] on line 13
Line 13:
$xml = simplexml_load_file('http://api.nbp.pl/api/exchangerates/tables/a/2017-04-05');
And other errors:
Warning: simplexml_load_file(): [{"table":"A","no":"067/A/NBP/2017","effectiveDate":"2017-04-05","rates":[{"curr in [PATH] on line 13
Warning: simplexml_load_file(): ^ in [PATH] on line 13
Notice: Trying to get property of non-object in [PATH] on line 18
Line 18:
$rate = (string)$xml->Rate[$i]->Mid;
What is difference between these xml's? What am I doing wrong? Could You help me?
Error 1 (invalid xml):
You're missing the ?format=xml at the end of the URL.
If you call http://api.nbp.pl/api/exchangerates/tables/a/2017-04-05 (without the format param) through a browser, it seems to default to XML automatically. If you call it through a script, it seems to default to JSON instead.
So it should work, just by changing
$xml = simplexml_load_file('http://api.nbp.pl/api/exchangerates/tables/a/2017-04-05');
to
$xml = simplexml_load_file('http://api.nbp.pl/api/exchangerates/tables/a/2017-04-05?format=xml');
Error 2 (property from non-object):
The xml looks like this:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfExchangeRatesTable xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ExchangeRatesTable>
<Table>A</Table>
<No>067/A/NBP/2017</No>
<EffectiveDate>2017-04-05</EffectiveDate>
<Rates>
<Rate>
<Currency>bat (Tajlandia)</Currency>
<Code>THB</Code>
<Mid>0.1151</Mid>
</Rate>
<Rate>
....
When you're trying to get the Rate, you're missing the first level node (ExchangeRatesTable).
Add it and it will work:
$rate = (string)$xml->ExchangeRatesTable->Rates->Rate[$i]->Mid

Parsing XML using JSON PHP and outputting data

I am trying to parse some xml in PHP and can build the correct url to fetch the data, but I am stuck on the process of determining how to look at the structure so I can avoid errors like this
Notice: Trying to get property of non-object in C:\wamp\www\sportchecker\soccer.php on line 39
Call Stack
# Time Memory Function Location
1 0.0020 252360 {main}( ) ..\sports.php:0
Here is an example URL http://api.pinnaclesports.com/v1/leagues?sportid=29, are their any tools that can tell me how to navigate through the tree in php code? The call I make with the API key has lots of data returned. Here is my code below
$url = "http://api.pinnaclesports.com/v1/feed?sportid=$sport_id&leagueid=$league_id&clientid=$client_id&apikey=$api_key&oddsformat=$oddsformat";
$json_string = file_get_contents($url);
$parsed_json = json_decode($json_string);
// output the xml data
$wSports = $parsed_json->sports->sport->id;
echo "Status : ${wSports} ";
// test if url is correct
echo $url;
Edit: here is a sample of the data, I am trying to get the teams and time back.
<rsp status="ok">
<fd>
<fdTime>1385326075704</fdTime>
<sports>
<sport>
<id>29</id>
<leagues>
<league>
<id>1739</id>
<events>
<event>
<startDateTime>2013-11-25T22:59:00Z</startDateTime>
<id>334321824</id>
<IsLive>No</IsLive>
<status>I</status>
<drawRotNum>2056</drawRotNum>
<homeTeam type="Team1">
<name>Atletico Huracan</name>
<rotNum>2054</rotNum>
</homeTeam>
<awayTeam type="Team2">
<name>Talleres Cordoba</name>
<rotNum>2055</rotNum>
</awayTeam>
<periods>
<period lineId="117000156">
<number>0</number>
<description>Game</description>
<cutoffDateTime>2013-11-25T22:59:00Z</cutoffDateTime>
<spreads>
<spread>
<awaySpread>0.25</awaySpread>
<awayPrice>1.869</awayPrice>
<homeSpread>-0.25</homeSpread>
<homePrice>1.97</homePrice>
</spread>
</spreads>
Use simplexml.
$sports = new SimpleXMLElement($parsedJson);
$sports->sport[0]->id

How to parse xml namespaces with DOMDocument and be sure to get objects

I'm trying to parse a xml response from other server.
I can get my needed objects from that xml. but some times and some how, I cant get some objects. and this error appears.
Fatal error: Call to a member function getElementsByTagName() on a non-object in line 91
I checked every thing and I think there is nothing wrong.
here is an example xml response:
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:domain="http://epp.nic.ir/ns/domain-1.0">
<response xmlns:domain="http://epp.nic.ir/ns/domain-1.0">
<result code="1000">
<msg>Command completed successfully</msg>
</result>
<resData xmlns:domain="http://epp.nic.ir/ns/domain-1.0">
<domain:infData xmlns:domain="http://epp.nic.ir/ns/domain-1.0">
<domain:name>pooyaos.ir</domain:name>
<domain:roid>305567</domain:roid>
<domain:status s="serverHold"/>
<domain:status s="irnicReserved"/>
<domain:status s="serverRenewProhibited"/>
<domain:status s="serverDeleteProhibited"/>
<domain:status s="irnicRegistrationDocRequired"/>
<domain:contact type="holder">pe59-irnic</domain:contact>
<domain:contact type="admin">pe59-irnic</domain:contact>
.
.
and more...
and I am trying to get this object domain:infData
I think the error is from this part.
when I am trying to get this object, domdocument returns null.
php code:
function DinfData()
{
$data = $this->dom->getElementsByTagName("infData")->item(0);
91: $name = $data->getElementsByTagName("name")->item(0)->nodeValue;
$roid = $data->getElementsByTagName("roid")->item(0)->nodeValue;
$update = $data->getElementsByTagName("upDate")->item(0)->nodeValue;
$crdate = $data->getElementsByTagName("crDate")->item(0)->nodeValue;
$exdate = $data->getElementsByTagName("exDate")->item(0)->nodeValue;
and more...
I marked line 91 in error.
thanks ....
edit
$this->dom is my DOMDocument object and has no error.
If nothing is wrong is there any better way to get elements?
You need to use DOMDocument::getElementsByTagNameNS() which is for use with namespaced elements. Find the namespace that domain points to and pass it to the method along with the target tag name e.g. roid or name.
Codepad Demo
$dom = new DOMDocument();
$dom->loadXML($xml);
$ns = 'http://epp.nic.ir/ns/domain-1.0';
$data = $dom->getElementsByTagNameNS($ns, 'infData')->item(0);
$roid = $data->getElementsByTagNameNS($ns, 'roid')->item(0)->nodeValue;
$name = $data->getElementsByTagNameNS($ns, 'name')->item(0)->nodeValue;
// repeat the same for others
echo $roid . "\n";
echo $name;
Outputs
305567
pooyaos.ir
Simply put in your url into simple_load_file()
<?php
$xml = simplexml_load_file($xmlfile);
print $xml->infData; // Sample content
?>
This is a easiest method
But infData is not your tagName. This XML uses namespaces (domain is your namespace). Don't have experience with that so I really can help you any futher then the hint where to look. The getElementsByTagName is not going to work, you need something like DOMXPath I think that's where you can do something with namespaces.
Sorry I can't be of futher help but since no one mentioned the namespaces I thought I would just add the answer anyway. Maybe it will help you Google for an answer.

PHP XPath query error after changing DOM

I always receive the message PHP Notice: Trying to get property of non-object in ... when trying to XPath-query a newly created node.
My XML file looks like this:
<products xmlns='http://example.com/products'>
<product id='1'>
<name>Product name</name>
</product>
</products>
My PHP file essentially applies an XPath query to get the existing <product> and a second query for its <name>. This works fine.
Then I insert a new <product> with the child <name> to the DOM root element and try the second query on the newly created elements. Getting the attribute works fine, but the second query, which should get the first child <name>'s value, fails with the PHP Notice Trying to get property of non-object in ....
$xmlFile = __DIR__ . '/products.xml';
$xml = new DOMDocument();
$xml->load($xmlFile);
$xml->formatOutput = true;
$xpath = new DOMXPath($xml);
$xpath->registerNamespace('p', $xml->lookupNamespaceUri($xml->namespaceURI));
/*
* query the first product's ID and name
*/
$product1 = Product::$xpath->query("//p:product[#id=1]")->item(0);
$product1Id = $product1->attributes->getNamedItem('id')->nodeValue;
// => "1"
$product1Name = $xpath->query("p:name", $product1)->item(0)->nodeValue;
// => "Product name"
/*
* create the second product
*/
$product2Node = $xml->createElement('product');
$product2Node->setAttribute('id', '2');
$product2NameNode = $xml->createElement('name', 'Test');
$product2Node->appendChild($product2NameNode);
$product2 = $xml->documentElement->appendChild($product2Node);
/*
* query the second product's ID and name
*/
$product2Id = $product2->attributes->getNamedItem('id')->nodeValue;
// => "2"
$product2Name = $xpath->query("p:name", $product2)->item(0)->nodeValue;
// => PHP Notice: Trying to get property of non-object in ...
$xml->save($xmlFile);
After running the PHP file, the XML looks correct:
<products xmlns='http://example.com/products'>
<product id='1'>
<name>Product name</name>
</product>
<product id='2'>
<name>Test</name>
</product>
</products>
I am really stuck on this, I tried to save the XML before querying, reloading the XML after saving, recreating the XPath object, etc.
I believe you need to use the createElementNS function (http://php.net/manual/en/domdocument.createelementns.php; you may also want to check on setAttributeNS -- http://www.php.net/manual/en/domelement.setattributens.php) instead of createElement in order to explicitly indicate that these elements belong to the http://example.com/products namespace.
$product2Node = $xml->createElementNS('http://example.com/products', 'product');
$product2Node->setAttribute('id', '2');
$product2NameNode = $xml->createElementNS('http://example.com/products', 'name', 'Test');
$product2Node->appendChild($product2NameNode);
(It's a little surprising that reloading the XML after saving did not resolve this, but without seeing the code that attempted to do the reload it's difficult to know what might have gone wrong.)

parse xml file in php

How to parse this type of files in php
I have tried using
<?php
$xml ="office.xml";
// get first book title
$title=$xml->featureMember->AA_OFFICE;
// show title
echo $title;
echo '<br/>';
?>
if iam using gml:featuremember instead of featuremember i am getting an error in syntax
if i use featuremember iam getting ) Notice: Trying to get property of non-object
<gml:boundedBy>
<gml:null>unknown</gml:null>
</gml:boundedBy>
<gml:featureMember>
<kgp:AA_OFFICE fid="AA_OFFICE.1">
<kgp:the_geom>
<gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#32645">
<gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">643630.3815,2498825.0741</gml:coordinates>
</gml:Point>
</kgp:the_geom>
<kgp:Name>MANMARK EXPORT PVT LTD</kgp:Name>
<kgp:Type/>
<kgp:Plot_No>55</kgp:Plot_No>
<kgp:Block_Name>AA</kgp:Block_Name>
</kgp:AA_OFFICE>
</gml:featureMember>
You are trying to use a string as an object. You have to create some form of XML Parsing object first. For example,
$xmlDoc = new DOMDocument();
$xmlDoc->load("office.xml");
More information
or
$xml = simplexml_load_file("office.xml");
More information
try to debug your xml
libxml_use_internal_errors(true);
$xml = simplexml_load_file("office.xml");
var_dump(libxml_get_errors());

Categories