Hi, i have a simple problem. When i try to convert an atom XML string to simplexml object or using simplexml_load_data function, it seems to drop many attributes data..
like in my original string i have
<?xml version="1.0" encoding="UTF-8"?>
<feed gd:kind="customsearch#search" xmlns="http://www.w3.org/2005/Atom" xmlns:cse="http://schemas.google.com/cseapi/2010" xmlns:gd="http://schemas.google.com/g/2005" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">
<title>Google Custom Search - flower</title>
<id>tag:www.googleapis.com,2010-09-29:/customsearch/v1?q=flower&&num=10&start=1&safe=off</id>
<author>
<name>- Google Custom Search</name>
</author>
<updated>1970-01-16T10:55:22.093Z</updated>
<opensearch:Url type="application/atom+xml" template="https://www.googleapis.com/customsearch/v1?q={searchTerms}&num={count?}&start={startIndex?}&lr={language?}&safe={cse:safe?}&cx={cse:cx?}&cref={cse:cref?}&sort={cse:sort?}&filter={cse:filter?}&gl={cse:gl?}&cr={cse:cr?}}&googlehost={cse:googleHost?}&c2coff={?cse:disableCnTwTranslation}&hq={cse:hq?}&hl={cse:hl?}&siteSearch={cse:siteSearch?}&siteSearchFilter={cse:siteSearchFilter?}&exactTerms={cse:exactTerms?}&excludeTerms={cse:excludeTerms?}&linkSite={cse:linkSite?}&orTerms={cse:orTerms?}&relatedSite={cse:relatedSite?}&dateRestrict={cse:dateRestrict?}&lowRange={cse:lowRange?}&highRange={cse:highRange?}&searchType={cse:searchType?}&fileType={cse:fileType?}&rights={cse:rights?}&imgsz={cse:imgsz?}&imgtype={cse:imgtype?}&imgc={cse:imgc?}&imgcolor={cse:imgcolor?}&alt=atom"/>
<opensearch:Query role="request" title="Google Custom Search - flower" totalResults="98800000" searchTerms="flower" count="10" startIndex="1" inputEncoding="utf8" outputEncoding="utf8" cse:safe="off" cse:cx="g"/>
<opensearch:Query role="cse:nextPage" title="Google Custom Search - flower" totalResults="98800000" searchTerms="flower" count="10" startIndex="11" inputEncoding="utf8" outputEncoding="utf8" cse:safe="off" cse:cx="0vv1rbg"/>
<opensearch:totalResults>98800000</opensearch:totalResults>
<opensearch:startIndex>1</opensearch:startIndex>
but when i convert it to xml using
$xml = simplexml_load_string($rs);
print_r($xml);
my output is like below. All the key information like number of searches, total results set is gone..
SimpleXMLElement Object
(
[title] => Google Custom Search - flower
[id] => tag:www.googleapis.com,2010-09-29:/customsearch/v1?q=flower&cx=&num=10&start=1&safe=off
[author] => SimpleXMLElement Object
(
[name] => Search Engine - Google Custom Search
)
[updated] => 1970-01-16T10:55:22.093Z
[entry] => Array
(
[0] => SimpleXMLElement Object
(
[id] => http://en.wikipedia.org/wiki/Flower
[updated] => 1970-01-16T10:55:22.093Z
[title] => <b>Flower</b> - Wikipedia, the free encyclopedia
[link] => SimpleXMLElement Object
(
[#attributes] => Array
(
[href] => http://en.wikipedia.org/wiki/Flower
[title] => en.wikipedia.org
)
)
[summary] => A <b>flower</b>, sometimes known as a bloom or blossom, is the reproductive structure <br> found in <b>flowering</b> plants (plants of the division Magnoliophyta, also called <b>...</b>
)
Those elements are not gone, you just can't "see" them in a standard dump, because they are in a different namespace. You can still iterate over them like this:
foreach ($xml->children('opensearch', TRUE) as $element) {
echo $element->getName(), "\n";
}
Where 'opensearch' indicates the namespace prefix and TRUE means that you used the document specific prefix instead of the full namespace url.
Related
I have this xml file (part of it):
<exchangerates xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" type="Valutakurser" author="Danmarks Nationalbank" refcur="DKK" refamt="1">
<dailyrates id="2020-10-23">
<currency code="AUD" desc="Australske dollar" rate="448,83"/>
<currency code="BGN" desc="Bulgarske lev" rate="380,44"/>
I want to get the rate from AUD, Australian dollar.
My xpath query looks like this:
$result = $xml->xpath("/exchangerates/dailyrates/currency[#code = 'AUD']");
It works and deliver this output:
Array ( [0] => SimpleXMLElement Object ( [#attributes] => Array ( [code] => AUD [desc] => Australske
dollar [rate] => 448,83 ) ) )
And now I am stuck. I want the [rate] value. But how? I have solved this in c# using a navigator.
But now I am using php. I could use javascript if necessary.
From the xpath point of view, you just need to add /#attributeName to your xpath.
/exchangerates/dailyrates/currency[#code = 'AUD']/#rate
I load some XML which produces a SimpleXML Object like so (only displaying one Object)
SimpleXMLElement Object
(
[Jobs] => SimpleXMLElement Object
(
[Job] => Array
(
[0] => SimpleXMLElement Object
(
[ID] => J000001
[Name] => Internal Time
[Description] => Use this job to record your internal and non-billable time for activities such as annual leave, sick leave, professional development, staff meetings etc
[Client] => SimpleXMLElement Object
(
[ID] => 8430219
[Name] => Fake Client
)
[ClientOrderNumber] => SimpleXMLElement Object
(
)
[State] => Planned
[StartDate] => 2016-03-21T00:00:00
[DueDate] => 2017-03-21T00:00:00
[InternalID] => 11442733
[Assigned] => SimpleXMLElement Object
(
[Staff] => SimpleXMLElement Object
(
[ID] => 344460
[Name] => Som Name
)
)
)
)
)
)
What I would like to do is create an array of the client Name and client ID. So I am aiming for something like so
[data] => array (
8430219 => Fake Client,
8430343 => Another Client,
etc
)
At the moment, I can get the name in place, but struggling with the id because it says it is an illegal offset type. This is what I have
foreach($oXML->Jobs as $oEntry) {
foreach ($oEntry->Job as $data) {
$jobsArray = array(
$data->Client->ID => $data->Client->Name
);
}
}
How can I create the array based on the SimpleXML Object I have?
Thanks
First of all, to obtain your desired array you can not use this syntax:
$jobsArray = array( $key => $val );
You have to use something like this:
$jobsArray[$key] = $val;
Otherwise, at each repeating loop, your syntax will override precedent array values.
Then, I suggest you to use XPath to simplify entire process. With XPath queries, you can retrieve a set of nodes with only one search.
Assuming you have this XML:
<?xml version="1.0"?>
<Jobs>
<Job>
<Client>
<ID>8430219</ID>
<Name>Fake Client</Name>
</Client>
<Client>
<ID>8430220</ID>
<Name>Fake Client 2</Name>
</Client>
</Job>
<Job>
<Client>
<ID>8430221</ID>
<Name>Fake Client 3</Name>
</Client>
</Job>
</Jobs>
With this xpath query:
$clients = $oXML->xpath( '/Jobs/Job/Client' );
you obtain in $clients all <Client> nodes. Then you can create your array in this way:
$result = array();
foreach( $clients as $client )
{
$result[$client->ID->__toString()] = $client->Name->__toString();
}
This is $result after foreach loop:
Array
(
[8430219] => Fake Client
[8430220] => Fake Client 2
[8430221] => Fake Client 3
)
Note that we have to cast as string single nodes (that are SimpleXML objects): this is absolutely necessary creating keys, otherwise the array assignment fails. You can obtain same result using (string) $client->ID instead of $client->ID->__toString()
Read more about SimpleXMLElement::xpath
Read more about XPath
I'm trying to parse some XML data using the php function simplexml_load_string() however it doesn't seem to work on elements where there is text and then further elements. Here is a sample data:
<?xml version="1.0"?>
<KPPRINT>
<CURRENTDATE>31/01/2015</CURRENTDATE>
<CURRENTTIME>21:43</CURRENTTIME>
<HEADER>
<ORDERNUMBER>CHECK NO: 69</ORDERNUMBER>
<CHECKNUMBER>ORDER NO: 16</CHECKNUMBER>
<REFTEXT>Party table</REFTEXT>
<REFTEXT>LOCATION 4</REFTEXT>
</HEADER>
<ITEM>VK Ice<QTY>1</QTY><PRICE>£0.03</PRICE><RECORD>57</RECORD><DEPT number="1" name="Wet Sales"/><GROUP number="5" name="FABs"/><CAT number="1" name="CATEGORY 1"/></ITEM>
<ITEM>Bramble<QTY>1</QTY><PRICE>£0.45</PRICE><RECORD>241</RECORD><DEPT number="1" name="Wet Sales"/><GROUP number="10" name="Cocktails"/><CAT number="1" name="CATEGORY 1"/></ITEM>
<ITEM>Gran Seleccion Rioja<QTY>1</QTY><PRICE>£19.95</PRICE><RECORD>225</RECORD><DEPT number="1" name="Wet Sales"/><GROUP number="9" name="Wines & Champagnes"/><CAT number="1" name="CATEGORY 1"/></ITEM>
<TRAILER>
<CLERK>Tom</CLERK>
<MACHINE>S000-T1</MACHINE>
<TIME>21:43</TIME>
<CONSEC>000023</CONSEC>
</TRAILER>
</KPPRINT>
This is the output I get:
Array
(
[CURRENTDATE] => 31/01/2015
[CURRENTTIME] => 21:43
[HEADER] => Array
(
[ORDERNUMBER] => CHECK NO: 69
[CHECKNUMBER] => ORDER NO: 16
[REFTEXT] => Array
(
[0] => Party table
[1] => LOCATION 4
)
)
[ITEM] => Array
(
[0] => Product 1
[1] => Product 2
[2] => Product 3
)
[TRAILER] => Array
(
[CLERK] => Tom
[MACHINE] => S000-T1
[TIME] => 21:43
[CONSEC] => 000023
)
)
The element text is there but the other elements within are not. Is there a simple option to the function or do I need to parse the whole string manually?
If it doesn't work with simplexml_load_string() you should try work with the data as recursive objects with DOMDocument because it allows to work with children nodes and I think it is not limited.
Please consider reading the following pages:
http://php.net/manual/en/class.domdocument.php
http://www.w3schools.com/php/php_xml_dom.asp
This question already has answers here:
Simple XML - Dealing With Colons In Nodes
(4 answers)
Closed 8 years ago.
I'm having trouble reading attributes from the Spreadshirt API with SimpleXML. I can't grab the xlink:href attribute from resources, which is what I need as it's not displays in the data received. Seem to be able to grab everything else, though.
This is the XML I'm reading in:
<articles xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://api.spreadshirt.net" xlink:href="http://api.spreadshirt.net/api/v1/shops/800323/articles?fullData=true" offset="0" limit="50" count="16" sortField="default" sortOrder="default">
<article isDuplicate="false" xlink:href="http://api.spreadshirt.net/api/v1/shops/800323/articles/100402428" id="100402428">
<name>Hammer T-Shirt</name>
<price>
<vatExcluded>13.33</vatExcluded>
<vatIncluded>16.00</vatIncluded>
<vat>20.00</vat>
<currency xlink:href="http://api.spreadshirt.net/api/v1/currencies/2" id="2"/>
</price>
<resources>
<resource mediaType="png" type="preview" xlink:href="http://image.spreadshirt.net/image-server/v1/products/125642560/views/1"/>
</resources>
</article>
</atricles>
This is the data coming back from SimpleXML:
SimpleXMLElement Object
(
[#attributes] => Array
(
[isDuplicate] => false
[id] => 27368595
)
[name] => Hammer Boxers
[price] => SimpleXMLElement Object
(
[vatExcluded] => 10.00
[vatIncluded] => 12.00
[vat] => 20.00
[currency] => SimpleXMLElement Object
(
[#attributes] => Array
(
[id] => 2
)
)
)
[resources] => SimpleXMLElement Object
(
[resource] => SimpleXMLElement Object
(
[#attributes] => Array
(
[mediaType] => png
[type] => preview
)
)
)
)
Does anyone have any ideas? I'm stumped.
The isDuplicate and id attributes are in the same namespace as the element.
The href element is in the http://www.w3.org/1999/xlink namespace, as indicated by the xlink prefix that is registered on the <articles> root element.
To access all the elements for the namespace, call $element->attributes('http://www.w3.org/1999/xlink').
The idea is that the root element could instead say xmlns:foobar="http://www.w3.org/1999/xlink", and each <article> would have foobar:href="..." attributes, and the code above would still work, because the bound prefix is just a way of improving readability. What counts is the namespace URL, not its prefix.
I am using an API to get a Block FIPS number but I have not been able to target that specific number within the XML file.
I did a print_r() on the xml output and here is what I get
SimpleXMLElement Object ( [#attributes] => Array ( [status] => OK [executionTime] => 6 ) [Block] => SimpleXMLElement Object ( [#attributes] => Array ( [FIPS] => 060730200252015 ) ) [County] => SimpleXMLElement Object ( [#attributes] => Array ( [FIPS] => 06073 [name] => San Diego ) ) [State] => SimpleXMLElement Object ( [#attributes] => Array ( [FIPS] => 06 [code] => CA [name] => California ) ) )
Here is the XML that is being generated
<Response xmlns="http://data.fcc.gov/api" status="OK" executionTime="10">
<Block FIPS="060730200252015"/>
<County FIPS="06073" name="San Diego"/>
<State FIPS="06" code="CA" name="California"/>
</Response>
I have been trying to get the Block FIPS Number like this:
$fccAPI = "http://data.fcc.gov/api/block/2010/find?latitude=$lat&longitude=$lng";
//echo $fccAPI;
$fccXML= simplexml_load_file($fccAPI);
print_r($fccXML);
//Echo FIPS Number
echo $fccXML->FIPS;
Please help me target the Block FIPS number.
You need to use the following:
echo $fccXML->Block[0]['FIPS'];
$fccXML is the root node, the <Response> element. ->Block[0] selects the first Block element, and to access an attribute, use the square brackets notation with the attribute name, i.e. ['FIPS'].
The SimpleXML documentation has numerous examples if you're having trouble with the syntax.