<ITEMS>
<ITEM ItemID="XY">
<ItemSearchName />
<ITEMDESCRIPTION>
<DESCRIPTION descriptionType="T" descriptionTypeTitle="Short" languageId="1" language="English">English description</DESCRIPTION>
<DESCRIPTION descriptionType="T" descriptionTypeTitle="Short" languageId="2" language="France">Fance description</DESCRIPTION>
</ITEMDESCRIPTION>
<ItemType>B</ItemType>
<ItemDepartment />
<ITEMDIMENSIONS>
<ItemDimensionUOM>m</ItemDimensionUOM>
</ITEMDIMENSIONS>
<ItemGrossWeihgt>0.00</ItemGrossWeihgt>
</ITEM>
</ITEMS>
This is an example of my XML file parsed with simplexml method. I do read ItemID attribute value with this code (just an example):
$item->attributes()->ItemID
My question is, how to access DESCRIPTION under DESCRIPTION attribute languageId = 1?
I can do this with foreach:
foreach ($item->ITEMDESCRIPTION->DESCRIPTION as $desc) {
if ($desc['languageId'] == '1') {
echo "<td>" . $desc . "</td>";
}
}
but I would prefer not to use foreach.
Another possibility is this:
$desc2 = $item->ITEMDESCRIPTION->DESCRIPTION[1];
but this is just the first DESCRIPTION and not the description with attribute languageId = 1.
Thanks for any suggestions!
You can also use xpath to get the particular value. Example:
$xml_string = '<ITEMS> <ITEM ItemID="XY"> <ItemSearchName /> <ITEMDESCRIPTION> <DESCRIPTION descriptionType="T" descriptionTypeTitle="Short" languageId="1" language="English">English description</DESCRIPTION> <DESCRIPTION descriptionType="T" descriptionTypeTitle="Short" languageId="2" language="France">Fance description</DESCRIPTION> </ITEMDESCRIPTION> <ItemType>B</ItemType> <ItemDepartment /> <ITEMDIMENSIONS> <ItemDimensionUOM>m</ItemDimensionUOM> </ITEMDIMENSIONS> <ItemGrossWeihgt>0.00</ItemGrossWeihgt> </ITEM></ITEMS>';
$xml = simplexml_load_string($xml_string);
$value = $xml->xpath('//ITEMDESCRIPTION/DESCRIPTION[#languageId="1"]')[0];
echo (string) $value; // English description
Or just simple foreach:
foreach($xml->ITEM->ITEMDESCRIPTION->DESCRIPTION as $desc) {
if($desc->attributes()['languageId'] == 1) {
echo (string) $desc; // English description
}
}
Related
I am trying to get the PAY where it has the ID 3 Where it says the label phone
but i really dont know how, i tried everything.
Thanks for helping!
Here is the XML code:
$books = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<data>
<login>1</login>
<arrStatsData>
<item>
<Id>500</Id>
<Label>website_name</Label>
<Data>
<item>
<Id>4</Id>
<Label>transactions</Label>
<Data>
<sum>2029.34</sum>
<cst>47.67575</cst>
<num>86</num>
<avg>23.6</avg>
<pay>1981.66</pay>
</Data>
</item>
<item>
<Id>3</Id>
<Label>Phone</Label>
<Data>
<sum>205</sum>
<cst>17.353</cst>
<num>205</num>
<avg>1</avg>
<pay>187.647</pay>
</Data>
</item>
......
PHP Code:
$xml = simplexml_load_string($arrResult); //load xml from above
foreach($xml->arrStatsData->item->Data as $item)
{
foreach($item->item as $DATA)
{
echo $DATA->Id.'<br>';
}
My result now is:
1981.66
187.647
-0.4448
Since you know some information that's tell the node apart from the rest you can use XPath to get the value directly instead of iterating through all of them:
<?php
$sxe = new SimpleXMLElement($books);
$pay = $sxe->xpath('//item[./Id=3]/Data/pay');
echo (string) $pay[0];
Ouput:
187.647
Your PHP code would be like this:
$xml = simplexml_load_string($books);
foreach($xml->arrStatsData->item->Data as $item)
{
//echo '$item;';
foreach($item->item as $DATA)
{
if($DATA->Id == '3'){
echo $DATA->Data->pay."<br/>";
}
}
}
It retrieve the pay value when the ID is equals to 3.
Rolando Isidoro was faster to recommend xpath, my solution is slightly different, that's why I post it, too:
$pay = (string)$xml->xpath("//item[Id = '3']/Data/pay")[0];
echo $pay;
see it working: http://codepad.viper-7.com/qzPlmp
First of all, thanks for the time reading this :)
I need help reordering an XML feed. I've tried many things and researched, but can't come up with a solution.
<xml>
<group>
<result>
<title>Title</title>
<url>URL</url>
<text>Text</text>
</result>
<result>
<title>Title</title>
<url>URL</url>
<text>Text</text>
</result>
</group>
<group region=top>
<result>
<title>Title</title>
<url>URL</url>
<text>Text</text>
</result>
</group>
<group type=bottom>
<result>
<title>Title</title>
<url>URL</url>
<text>Text</text>
<moreinfo>
<result>
<title>Title</title>
</result>
<result>
<title>Title</title>
</result>
</moreinfo>
</result>
</group>
</xml>
What I am trying to do is re-order the XML feed to display each node inside 'result'. However, I need the feed reordered so the 'result' from 'group region=top' is at the top, then the results from 'group', then results from 'group region=bottom'.
You might notice there is another 'result' tag nested inside of a 'result' tag in 'group region=bottom', which is causing most of the issues. The way I envision a solution to this is with the following pseudo-code:
$books = $doc->getElementsByTagName( "result" );
foreach( $books as $book )
{
if (parent_attribute = top){
$toptitle = $book->getElementsByTagName( "title" );
$toptitle = $toptitle->item(0)->nodeValue;
$topnew[] =array("title"=>$toptitle);
}
if (parent_attribute = null){
$middletitle = $book->getElementsByTagName( "title" );
$middletitle = $middletitle->item(0)->nodeValue;
$middlenew[] =array("title"=>$middletitle);
}
if (parent_attribute = bottom){
$bottomtitle = $book->getElementsByTagName( "title" );
$bottomtitle = $bottomtitle->item(0)->nodeValue;
if (parent_element = moreinfo){
$moretitle = $book->getElementsByTagName( "title" );
$moretitle = $moretitle->item(0)->nodeValue;
}
$bottomnew[] =array("title"=>$bottomtitle, "more"=>$moretitle);
}
}
The XML you posted is invalid and not consistent, as attribute values have to be enclosed in "", for consistency see my comment above.
Here's how I do it using simplexml and xpath, it can be easily adapted to DOM as well.
$xml = simplexml_load_string($x); // assuming XML in $x
$regions['top'] = $xml->xpath("group[#region='top']/result");
$regions['middle'] = $xml->xpath("group[not(#*)]/result"); // <group> with no attribute
$regions['bottom'] = $xml->xpath("group[#region='bottom']/result");
// output:
foreach ($regions as $region => $results) {
echo "$region:<br />";
foreach ($results as $result) {
echo $result->title . "<br />";
if (count($result->moreinfo) > 0)
foreach ($result->moreinfo->result as $subresult)
echo "____$subresult->title<br />";
} // foreach $results
} // foreach $regions
see it working: http://codepad.viper-7.com/5adWxC
I have this XML code :
<?xml version="1.0"?>
<Days>
<day value="1">
<Imsaak>04:59</Imsaak>
<Fajr>05:09</Fajr>
<Sunrise>06:23</Sunrise>
<Dhuhr>12:39</Dhuhr>
<Asr>16:12</Asr>
<Sunset>18:55</Sunset>
<Maghrib>19:10</Maghrib>
<Isha>20:04</Isha>
</day>
<day value="2">
<Imsaak>04:58</Imsaak>
<Fajr>05:08</Fajr>
<Sunrise>06:22</Sunrise>
<Dhuhr>12:39</Dhuhr>
<Asr>16:12</Asr>
<Sunset>18:56</Sunset>
<Maghrib>19:11</Maghrib>
<Isha>20:05</Isha>
</day>
</Days>
and I want to select <day> node depending on the attribute value
I am using SimpleXMLElement class but I don't how to select with arrtibute value.
how I can do that??
EDIT: my code :
include 'days.xml';
$xml = new SimpleXMLElement($xmlstr);
foreach ($xml->day as $day) {
// process data
}
from php manual SimpleXMLElement::attributes (little bit edited)
Considering this data:
<?xml version="1.0" encoding="utf-8"?>
<data>
<item ID="30001">
<Company>Navarro Corp.</Company>
</item>
<item ID="30002">
<Company>Performant Systems</Company>
</item>
<item ID="30003">
<Company>Digital Showcase</Company>
</item>
</data>
Example of listing both the ID Attribute and Company Element values:
<?php
$xmlObject = new SimpleXMLElement($xmlstring);
foreach ($xmlObject->children() as $node) {
$arr = $node->attributes(); // returns an array
if(in_array("30002", $arr)){ // search the value of an attribute
print ("Company=".$node->Company);
}
//depending of your needs, you could use a switch / case instead of use an if
}
?>
$xml = new SimpleXMLElement($xmlStr)
$xml->day[0]->attribute()->value;//will echo out 1
of course you can loop through all of the day like this:
foreach($sml->day as $day){
$day->attribute()->value; //will trace out 1 and then 2
}
Consider the following code :
$dom = new DOMDocument();
$dom->loadXML($file);
$xmlPath = new DOMXPath($dom);
$arrNodes = $xmlPath->query('*/item');
foreach($arrNodes as $item){
//missing code
}
The $file is an xml and each item has a title and a description.
How can I display them (title and description)?
$file = "<item>
<title>test_title</title>
<desc>test</desc>
</item>";
I suggest using php's simplexml, with that, you still get xpath functionality, but with easier approach, for example you would access attributes like this:
$name = $item['name'];
Here's an example:
xmlfile.xml:
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<items>
<item title="Hello World" description="Hellowing the world.." />
<item title="Hello People" description="greeting people.." />
</items>
</xml>
do.php:
<?php
$xml_str = file_get_contents('xmlfile.xml');
$xml = new SimpleXMLElement($xml_str);
$items = $xml->xpath('*/item');
foreach($items as $item) {
echo $item['title'], ': ', $item['description'], "\n";
}
If your item looks like this:
<item>
<title>foo</title>
<description>frob</description>
</item>
You could use getElementsByTagName() and nodeValue:
foreach($arrNodes as $item){
print $item->getElementsByTagName('title')->item(0)->nodeValue;
}
Are title and description attributes? E. g. does an item look like this:
<item title="foo" description="frob" />
If so, you could just use getAttribute():
...
foreach($arrNodes as $item){
print $item->getAttribute('title');
}
The right XPath expression should be:
/*/item/title | /*/item/desc
Or
/*/item/*[self::title or self::desc]
This is evaluate to a node set with title and desc element in document order
I have been asked to parse a simple file which is stored as an XML file, the data is to be then put into a mysql database.
However I have absolutely no clue what to do and after looking online all the examples given seem either too complicated for my problem or not the right solution. The XML file looks like this:
<shop>
<products>
<product id="1" name="Cornetto" price="1.20" description="Traditional Cornetto" />
<product id="2" name="Smarties" price="1.00" description="Smarties Icecream" />
</products>
<stocks>
<stock id="1" amount="242" price="pounds" />
<stock id="2" amount="11" price="pounds" />
</stocks>
I've tried looking at SimpleXML and I think that's the direction I have to go but I just have no idea.
Any help or pointers would be great.
I personally like the normal XMl formatting so I changed it since its a bit more readable but this is how you can use it:
$xmlstr = <<<XML
<?xml version='1.0' standalone='yes'?>
<shop>
<products>
<product>
<id>1</id>
<name>Cornetto</name>
<price>1.20</price>
<description>Traditional Cornetto</description>
</product>
<product>
<id>2</id>
<name>Smarties</name>
<price>1.00</price>
<description>Smarties Icecream</description>
</product>
</products>
<stocks>
<stock>
<id>1</id>
<amount>242</amount>
<price>pounds</price>
</stock>
<stock>
<id>2</id>
<amount>11</amount>
<price>pounds</price>
</stock>
</stocks>
</shop>
XML;
Handling part:
$xml = new SimpleXMLElement($xmlstr);
echo 'single value: <br />';
echo $xml->products->product[0]->id; // get single value
echo '<br /><br />';
//Loop trough multiple products
echo 'multiple values: <br />';
foreach($xml->products->product as $product)
{
echo $product->id.' - ';
echo $product->name.' - ';
echo $product->price.' - ';
echo $product->description;
echo '<br/>';
}
Assuming the file is called data.xml
$string = file_get_contents('data.xml') reads the entire file into $string.
$xml = new SimpleXMLElement($string); parses that string, and converts it into an object tree similar to the actual document. So if that's the document -
<root>
<b>
<c>first</c>
<c>second</c>
</b>
</root>
The SimpleXMLElement object would be used like:
$xml->b // gets all children of b (c[0] and c[1])
print $xml->b->c[0] // gets the first c, will print "first"
You can use for example SimpleXMLElement and xpath
<?php
$xmlStr = <<<EOF
<?xml version="1.0"?>
<shop>
<products>
<product id="1" name="Cornetto" price="1.20" description="Traditional Cornetto" />
<product id="2" name="Smarties" price="1.00" description="Smarties Icecream" />
</products>
<stocks>
<stock id="1" amount="242" price="pounds" />
<stock id="2" amount="11" price="pounds" />
</stocks>
</shop>
EOF;
$xml=new SimpleXMLElement($xmlStr);
// get product line with xpath for example
$products=$xml->xpath("/shop/products/product");
if ($products) {
// loop over each product node
foreach ($products as $product) {
// do whatever you want with the data
echo("id=>".$product["id"].", name=>".$product["name"]."<br/>");
}
}
// same for stock
// get product line with xpath for example
$stocks=$xml->xpath("/shop/stocks/stock");
if ($stocks) {
// loop over each product node
foreach ($stocks as $stock) {
// do whatever you want with the data
echo("id=>".$stock["id"].", amount=>".$stock["amount"]."<br/>");
}
}
?>
$xml = simplexml_load_file($filename);
foreach($xml->product as $product) {
foreach($product->attributes() as $name => $attribute) {
echo "$name = $attribute";
}
}
$xml = simplexml_load_file($filename);
foreach($xml->products->product as $not)
{
foreach($not->attributes() as $a => $b)
{
echo $a,'="',$b,"\"<br />";
}
}