$xml = '<?xml version="1.0" encoding="UTF-8"?>
<stw:ThumbnailResponse xmlns:stw="http://www.shrinktheweb.com/doc/stwresponse.xsd">
<stw:Response>
<stw:ThumbnailResult>
<stw:Thumbnail Exists="true">http://imagelink.com</stw:Thumbnail>
<stw:Thumbnail Verified="false">delivered</stw:Thumbnail>
</stw:ThumbnailResult>
<stw:ResponseStatus>
<stw:StatusCode>refresh</stw:StatusCode>
</stw:ResponseStatus>
<stw:ResponseTimestamp>
<stw:StatusCode>1413812009</stw:StatusCode>
</stw:ResponseTimestamp>
<stw:ResponseCode>
<stw:StatusCode>HTTP:200</stw:StatusCode>
</stw:ResponseCode>
<stw:CategoryCode>
<stw:StatusCode></stw:StatusCode>
</stw:CategoryCode>
<stw:Quota_Remaining>
<stw:StatusCode>132</stw:StatusCode>
</stw:Quota_Remaining>
<stw:Bandwidth_Remaining>
<stw:StatusCode>999791</stw:StatusCode>
</stw:Bandwidth_Remaining>
</stw:Response>
</stw:ThumbnailResponse>';
$dom = new DOMDocument;
$dom->loadXML($xml);
$result = $dom->getElementsByTagName('stw:Thumbnail')->item(0)->nodeValue;
$status = $dom->getElementsByTagName('stw:Thumbnail')->item(0)->nodeValue;
echo $result;
Having the above code should output http://imagelink.com and $status should hold "delivered" - but none of these work instead I am left with the error notice that:
Trying to get property of non-object
I have tried different xml parsing alternatives like simplexml (but that did not work when the tag names have : in it ) and i tried looping through the each scope in the xml (ThumbNailresponse, response and then thumbnailresult) without luck.
How can i get the values inside stw:Thumbnail?
You need to specify a namespace and the method DOMDocument::getElementsByTagName can't handle it. In the manual:
The local name (without namespace) of the tag to match on.
You can use DOMDocument::getElementsByTagNameNS instead:
$dom = new DOMDocument;
$dom->loadXML($xml);
$namespaceURI = 'http://www.shrinktheweb.com/doc/stwresponse.xsd';
$result = $dom->getElementsByTagNameNS($namespaceURI, 'Thumbnail')->item(0)->nodeValue;
Using simple xml you could use ->children() method on this one:
$xml = simplexml_load_string($xml_string);
$stw = $xml->children('stw', 'http://www.shrinktheweb.com/doc/stwresponse.xsd');
echo '<pre>';
foreach($stw as $e) {
print_r($e);
// do what you have to do here
}
This code actually runs just fine for me ---
Typically, that sort of error means you may've made a typo on your $dom object - double check it and try again.
Also, it is notable that you'll want to change the item(0) to item(1) when you're setting your $status variable.
$result = $dom->getElementsByTagName('stw:Thumbnail')->item(0)->nodeValue;
$status = $dom->getElementsByTagName('stw:Thumbnail')->item(0)->nodeValue;
Related
I am getting a xml response from doing:
$foo = $client->__doRequest (parameters here)
when I echo out $foo I get the xml exactly as I'm told I should. The problem is now I want to extract some values from the xml. Now the easiest way I can see to do that is to convert it to a php array and then is super simple to get value and do lots of lovely stuff with but I seem to be having trouble doing this. Have seen a lot of examples using simple_load_xml but all I get is 'Notice: Array to string conversion in'. When I var_dump '$foo' I get 'string 'xml' '.
What am I doing wrong?
As suggested by #CD001 I persevered with DOMDocument and figured it out in the end with the following code:
$dom = new DOMDocument;
$dom->loadXML($xml);
$things = $dom->getElementsByTagName('chocolate');
/** I only had a single result so had to do it this way rather then a loop**/
if($things->length > 0) {
$node = $things->item(0);
$chocolate = $node->nodeValue;
}
else {
// empty result set
}
echo $chocolate;
bah! JSON is so much nicer...
Use Xpath:
$dom = new DOMDocument;
$dom->loadXML($xml);
$xpath = new DOMXpath($dom);
// get content of the first chocolate element node as a string
$chocolate = $xpath->evaluate('string(//chocolate)');
echo $chocolate;
I'm trying to parse an xml data that I'm getting via an api call. I can use file_get_contents to read into a string but simpleXML_load_string seems to fail to read it. I can save it to a file and then simpleXML_load_file works. But I would rather not write the contents to a file. I can't seem to understand how to use DOM or XMLParse with this either. I'm new to PHP and parsing XML. The output data from the api call is below.
<Search>
<DS_Rating>DS3</DS_Rating>
<Overall>17.5</Overall>
<LargestGiftLow>0</LargestGiftLow>
<LargestGiftHigh>0</LargestGiftHigh>
<EstimatedCapacityRange>I - $15,000 - $24,999</EstimatedCapacityRange>
<EstimatedCapacity>20452</EstimatedCapacity>
<RealEstateEst>270073</RealEstateEst>
<RealEstateCount>1</RealEstateCount>
<LikelyMatchesCount>0</LikelyMatchesCount>
<LikelyMatchesTotal>0</LikelyMatchesTotal>
<FndBoard></FndBoard>
<GSBoard></GSBoard>
<PoliticalLikelyCount>0</PoliticalLikelyCount>
<PoliticalLikelyTotal>0</PoliticalLikelyTotal>
<BusinessRevenues>0</BusinessRevenues>
<SECStockValue>0</SECStockValue>
<SECInsider></SECInsider>
<MarketGuide></MarketGuide>
<IRS990PF></IRS990PF>
<RealEstateTrust></RealEstateTrust>
<MarketGuideComp>0</MarketGuideComp>
<MarketGuideOptions>0</MarketGuideOptions>
<BusinessAffiliation></BusinessAffiliation>
<Pension></Pension>
<PensionAssets>0</PensionAssets>
<CorpTech></CorpTech>
<Pilot></Pilot>
<AirplaneOwner></AirplaneOwner>
<Boat></Boat>
<submit_time>2014-03-11 15:48:45</submit_time>
</Search>
Figured out that the issue was that what I was seeing in the browser was actually a php output with html_entiity encoded. I was able to process it with the code below which let me load it with simplexml.
$rawxml = html_entity_decode($rawxml);
$rawxml = str_replace(array(' ', "<pre>"), '', $rawxml);
$rawxml = utf8_encode($rawxml);
$xml = simplexml_load_string($rawxml);
If you XML is in a file use
simplexml_load_file
if you have it in a string use
simplexml_load_string
Then you can use the following code to access it.
<?php
$yourxml = simplexml_load_file('your.xml');
echo $yourxml->search[0]->DS_Rating;
?>
This would then output
DS3
to the browser via the 'echo' in your code. I hope this points you in the correct direction.
Try to use this:
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8" ?>'.$yourXMLString);
In DOM you load the XML into a DOMDocument and create a DOMXpath instance for it.
$dom = new DOMDocument();
$dom->loadXml($xmlString);
//$dom->load($xmlFile);
$xpath = new DOMXpath($dom);
DOMXpath::evaluate() is used to fetch data from the DOM.
$rating = $dom->evaluate('string(/Search/DS_Rating)');
An Xpath expression like /Search/DS_rating always returns a node list. You can use foreach() to iterate it. The string() function in Xpath takes the first node from the list and casts it into a string. If here is not node in the list the result is an empty string.
$xmlString = <<<'XML'
<Search>
<DS_Rating>DS3</DS_Rating>
<Overall>17.5</Overall>
</Search>
XML;
$dom = new DOMDocument();
$dom->loadXml($xmlString);
$xpath = new DOMXpath($dom);
var_dump(
$xpath ->evaluate('string(/Search/DS_Rating)')
);
Output: https://eval.in/118921
string(3) "DS3"
<?xml version="1.0" encoding="UTF-8"?>
<AddProduct>
<auth><id>vendor123</id><auth_code>abc123</auth_code></auth>
</AddProduct>
What am I doing wrong to get : Fatal error: Call to undefined method DOMNodeList::getElementsByTagName()
$xml = $_GET['xmlRequest'];
$dom = new DOMDocument();
#$dom->loadXML($xml);
$xpath = new DOMXPath($dom);
$auth = $xpath->query('*/auth');
$id = $auth->getElementsByTagName('id')->item(0)->nodeValue;
$code = $auth->getElementsByTagName('auth_code')->item(0)->nodeValue;
You could retrieve the data (in the XML you posted) you want using XPath only:
$id = $xpath->query('//auth/id')->item(0)->nodeValue;
$code = $xpath->query('//auth/auth_code')->item(0)->nodeValue;
You are also calling getElementsByTagName() on $auth (DOMXPath), as #Ohgodwhy pointed out in the comments, which is causing the error. If you want to use it, you should call it on $dom.
Your XPath expression returns the auth child of the current (context) node. Unless your XML file is different, it's clearer to use one of:
/*/auth # returns auth nodes two levels below root
/AddProduct/auth # returns auth nodes in below /AddProduct
//auth # returns all auth nodes
This is what I came up with after reviewing php's documentation (http://us1.php.net/manual/en/class.domdocument.php, http://us1.php.net/manual/en/domdocument.loadxml.php, http://us3.php.net/manual/en/domxpath.query.php, http://us3.php.net/domxpath)
$dom = new DOMDocument();
$dom->loadXML($xml);
$id = $dom->getElementsByTagName("id")->item(0)->nodeValue;
$code = $dom->getElementsByTagName("auth_code")->item(0)->nodeValue;
As helderdarocha and Ohgodwhy pointed out, the getElementByTagName is a DOMDocument method not a DOMXPath method. I like helderdarocha's solution that only uses XPath, the solution I posted accomplishes the same thing but only uses the DOMDocument.
I have the following code
$dom = new DOMDocument('1.0', 'utf-8');
$headerNS = $dom->createElementNS('http://somenamespace', 'ttauth:authHeader');
$accesuser = $dom->createElementNS('http://somenamespace', 'ttauth:Accessuser','aassdd');
$accesscode = $dom->createElementNS('http://somenamespace', 'ttauth:Accesscode','aassdd');
$headerNS->appendChild($accesuser);
$headerNS->appendChild($accesscode);
echo "<pre>";
echo ($dom->saveXML($headerNS));
echo "</pre>";
IT will produce the following xml as output
<?xml version="1.0" ?>
<ttauth:authHeader xmlns:ttauth="http://somenamespace">
<ttauth:Accessuser>
ApiUserFor136
</ttauth:Accessuser>
<ttauth:Accesscode>
test1234
</ttauth:Accesscode>
</ttauth:authHeader>
But I want the following output
<ttauth:authHeader xmlns:ttauth="http://somenamespace">
<ttauth:Accessuser xmlns:ttauth="http://somenamespace">
aassdd
</ttauth:Accessuser>
<ttauth:Accesscode xmlns:ttauth="somenamespace">
aassdd
</ttauth:Accesscode>
</ttauth:authHeader>
See the xmlns is not included in elements other than root element but I want xmlns to be included in all elements Is there anything I am doing wrong ??
Probably the PHP parser does not add renaming of the same namespace "http://somenamespace" with the same prefix "ttauth" because it is redundant. Both xmls you shown ( the output and expected ) are equivalent. If you want to be sure you have the namespaces attributes as you want, you should add them manually by using addAtribute - http://www.php.net/manual/en/domdocument.createattribute.php. See the following code snippet:
$domAttribute = $domDocument->createAttribute('xmlns:ttauth');
$domAttribute->value = 'http://somenamespace';
$accessuser->appendChild($domAttribute);
Hope it helps
instead of using
$accesuser = $dom->createElementNS('http://somenamespace', 'ttauth:Accessuser','aassdd');
I used
$accesuser = $dom->createElement('http://somenamespace', 'ttauth:Accessuser','aassdd');
and then
$accesuser->setAttribute('xmlns:ttauth', ('http://somenamespace');
it works fine for any number of nodes
I am trying to parse all script src link values, but I get an empty array.
$dom = new DOMDocument();
$file = #$dom->loadHTML($remote);
$xpath = new DOMXpath($dom);
$link = $xpath->query('//script[contains(#src, "pcode")]');
$return = array();
foreach($link as $links) {
$return[] = $links->nodeValue;
}
Your XPATH query looks valid, should grab every <script> with attribute src containing pcode.
If it's returning an empty array, there's a few things to check:
Make sure the DOM document and loading, and there are not errors when loading it into XPATH. It could be possible that the suppressed DOM->load is giving an error or warning. If you query elsewhere and it works, then ignore this.
Make sure the tags in your document are case-matching.
Try
$link = $xpath->query("//script[contains(#src, 'pcode')]");
Seems silly, just switching quote marks, but you never know.
Be sure to check namespaces. If your HTML contains a declaration like this
<html xmlns="http://www.w3.org/1999/xhtml">
You'll need to register the namespace with the document
$xp = new domxpath( $xml);
$xp->registerNamespace('html', 'http://www.w3.org/1999/xhtml' );
And Look for elements like this
$elements = $xp->query( "//html:script", $xml );
Namespaces, because paranoia breeds confidence.