Trying to extract simplexml attribute - php

I have an XML file that looks like this:
<?xml version="1.0" encoding="ISO-8859-1"?>
<products>
<product sku="CATDJ" type="CAT" vendor="DJ" active="1" on_sale="0" discountable="0">
<name>CATALOGS</name>
<short_description><![CDATA[The DJ catalog features 182 pages]]></short_description>
<long_description><![CDATA[The DJ catalog features 182 pages.]]></long_description>
<price>1.5</price>
<stock_quantity>65</stock_quantity>
<release_date>2003-05-06T00:00:00-04:00</release_date>
<barcode>782421791315</barcode>
</product>
....
I can get the price, stock_quatity, and barcode, but not the sku, active or discountable data.
This is what my code looks like this:
$myinv = simplexml_load_file('http://www.*******.com/products.xml');
foreach ($myinv as $invinfo):
$sku = $invinfo->products->product->sku;
$active = $invinfo->products->product->active;
$deductible = $invinfo->products->product->discountable;
$qty=$invinfo->stock_quantity;
$price=$invinfo->price;
$upc=$invinfo->barcode;
What Am I doing wrong? BTW, I'm new to php.
Thank you for your help.

I always typecast everything I get from SimpleXML, because it always returns a SimpleXMLElement. var_dump your variables to see for yourself.
<?php
$xml = '<?xml version="1.0" encoding="ISO-8859-1"?>
<products>
<product sku="CATDJ" type="CAT" vendor="DJ" active="1" on_sale="0" discountable="0">
<name>CATALOGS</name>
<short_description><![CDATA[The DJ catalog features 182 pages]]></short_description>
<long_description><![CDATA[The DJ catalog features 182 pages.]]></long_description>
<price>1.5</price>
<stock_quantity>65</stock_quantity>
<release_date>2003-05-06T00:00:00-04:00</release_date>
<barcode>782421791315</barcode>
</product>
</products>';
$myinv = new SimpleXMLElement($xml);
$products = $myinv->product;
foreach ($products as $product){
$attrs = $product->attributes();
$sku = $attrs->sku;
$active = $attrs->active;
$discountable = $attrs->discountable;
$qty = $product->stock_quantity;
$price = $product->price;
$upc = $product->barcode;
echo (string)$sku . "<br>\n";
echo (string)$active . "<br>\n";
echo (string)$discountable . "<br>\n";
echo (string)$qty . "<br>\n";
echo (string)$price . "<br>\n";
echo (string)$upc . "<br>\n";
}
?>

XPath can do the job of getting the value of an attribute with $xpath->query("//product[#name='sku']/#value");.

Related

Load Foreach loop into string as XML

I'm trying to load a foreach into a string formatted as XML.
I've tried as follows
<?php
$data = '<?xml version="1.0" encoding="utf-8" ?><markers>';
foreach ($entries as $entry => $marker ) {
'<marker name="' . $marker->getName() . '"'.'lat="' . $marker->getLatitude() . '"'.'lng="' . $marker->getLongitude() . '"'.'address="' . $marker->getAddressLineOne() . '"'.'address2="' . $marker->getAddressLineTwo() . '"'.'city="' . $marker->getCitySuburb() . '"'.'state="' . $marker->getState('fieldName') . '"'.'postal="' . $marker->getPostCode() . '"'.'country="' . $marker->getCountry('fieldName') . '"'.'phone="' . $marker->getPhone() . '"'.'email="' . $marker->getEmail() . '"'.'web="' . $marker->getWebSite() . '"'.'/>';
}
'</markers>';
?>
But what I end up getting is:
nothing in the $data variable
for some reason each item is nesting in the previous item
Basically I would like to achieve the following result:
<?php
$data = '<?xml version="1.0" encoding="utf-8"?>
<markers>
<marker name="Chipotle Minneapolis" lat="44.947464" lng="-93.320826" category="Restaurant" address="3040 Excelsior Blvd" address2="" city="Minneapolis" state="MN" postal="55416" country="US" phone="612-922-6662" email="info#chipotle.com" web="http://www.chipotle.com" />
<marker name="Chipotle St. Louis Park" lat="44.930810" lng="-93.347877" category="Restaurant" address="5480 Excelsior Blvd." address2="" city="St. Louis Park" state="MN" postal="55416" country="US" phone="952-922-1970" email="info#chipotle.com" web="http://www.chipotle.com" />
<marker name="Chipotle Minneapolis" lat="44.9553438" lng="-93.29719699999998" category="Restaurant, Bar" address="2600 Hennepin Ave." address2="" city="Minneapolis" state="MN" postal="55404" country="US" phone="612-377-6035" email="info#chipotle.com" web="http://www.chipotle.com" />
</markers>';
?>
Thanks
Said
Revised code
<?php
$data = simplexml_load_string("<markers />");
foreach ($entries as $entry => $marker ) {
$newMarker = $data->addChild("marker");
$newMarker->addAttribute("name", $marker->getName());
$newMarker->addAttribute("lat", $marker->getLatitude());
$newMarker->addAttribute("lng", $marker->getLongitude());
$newMarker->addAttribute("state", $marker->getPostCode());
}
echo $data->asXML();
?>
<?php
echo var_dump($data);
?>
After the first line where you use
$data = '<?xml version="1.0" encoding="utf-8" ?><markers>';
you don't add any of the further text onto the variable. You need to use something like
$data .='<marker name="' . $marker->getName() .`
(with the dot before the = to add the value), you also need to be careful with the spacing and the quotes.
I would also recommend using something like SimpleXML to build the XML rather than using put text, it is longer code but safer. Something like...
$xml = simplexml_load_string("<markers />");
foreach ($entries as $entry => $marker ) {
$newMarker = $xml->addChild("marker");
$newMarker->addAttribute("name", $marker->getName());
$newMarker->addAttribute("lat", $marker->getLatitude());
$newMarker->addAttribute("lng", $marker->getLongitude());
// Repeat for all attributes
}
echo $xml->asXML();
Since it's not clear to me how $entries are generated, I'll make up some data in couple of arrays and create a simplified version of your expected output, with the help of a function borrowed from here. Obviously, you'll need to modify it to fit your actual code.
$data = <<<XML
<?xml version="1.0" encoding="utf-8"?>
<markers>
</markers>
XML;
$xml = simplexml_load_string($data);
function sxml_append(SimpleXMLElement $to, SimpleXMLElement $from) {
$toDom = dom_import_simplexml($to);
$fromDom = dom_import_simplexml($from);
$toDom->appendChild($toDom->ownerDocument->importNode($fromDom, true));
}
$stores = ["Chipotle Chicago","Chipotle St. Louis Park","Chipotle Minneapolis"];
$locations = ["Chicago","St. Louis Park","Minneapolis"];
$destination = $xml->xpath('//markers');
foreach(array_combine($stores, $locations) as $store => $location) {
$tm = simplexml_load_string('<marker name="xxx" city="yyy"/>');
$tmxml = $tm->xpath('//marker')[0];
$tmxml['name'] = $store;
$tmxml['city'] = $location;
sxml_append($destination[0], $tmxml);
}
echo $xml->asXML();
Output:
<?xml version="1.0" encoding="UTF-8"?>
<markers>
<marker name="Chipotle Chicago" city="Chicago" />
<marker name="Chipotle St. Louis Park" city="St. Louis Park" />
<marker name="Chipotle Minneapolis" city="Minneapolis" />
</markers>

How to edit my code to save to mySQL from the beginning of XML?

I have this XML feed below I am trying to import into MySQL for all the products.
For example, inside the table XML_FEED I want something like
shop - product_id - product_name - product_link - .......
mywebstore - 322233 - MadBiker 600 - .........
mywebstore - 324633 - Samsung S4 - .........
The code until now it works only if the XML begins from <products> and not from <mywebstore>
How to change my code to do this ?
$xml = simplexml_load_file("test.xml");
foreach($xml->product as $product)
{
$columns = array();
$data = array();
foreach($product->children() as $child)
{
echo $child->getName() . ": " . $child . "<br />";
$columns[] = $child->getName();
$data[] = mysql_real_escape_string((string)$child);
}
$col = '`'. implode('`,`',$columns) .'`';
$val = "'". implode("','",$data)."'";
$query = "INSERT INTO XML_FEED ($col) VALUES ($val)";
echo $query;
mysql_query($query);
}
Here is the XML:
<?xml version="1.0" encoding="UTF-8"?>
<mywebstore>
<created_at>2010-04-08 12:32</created_at>
<products>
<product>
<id>322233</id>
<name><![CDATA[MadBiker 600]]></name>
<link><![CDATA[http://www.mywebstore.co.uk/product/322233]]></link>
<image><![CDATA[http://www.mywebstore.co.uk/product/322233.jpg]]></image>
<category><![CDATA[Outdor > Extreme Sports]]></category>
<price_with_vat>322.33</price_with_vat>
</product>
...
...
...
</products>
</mywebstore>
Use This code:
<?php
$xml = simplexml_load_file('test.xml');
foreach($xml->products->product as $product)
{
$columns = array();
$data = array();
foreach($product->children() as $child)
{
echo $child->getName() . ": " . $child . "<br />";
$columns[] = $child->getName();
$data[] = mysql_real_escape_string((string)$child);
}
$col = '`'. implode('`,`',$columns) .'`';
$val = "'". implode("','",$data)."'";
$query = "INSERT INTO XML_FEED ($col) VALUES ($val)";
echo $query;
mysql_query($query);
}
?>
This should work for you:
<?php
//Xml stuff
$xml = simplexml_load_file("file.xml");
//Database stuff
$hostname = "localhost";
$username = "root";
$password = "";
try {
//DB Connection
$dbh = new PDO("mysql:host=$hostname;dbname=dbname", $username, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected to Database<br/>";
foreach($xml->products->product as $data) {
$sql = "INSERT INTO XML_FEED (shop, product_id, product_name, product_link, product_image, product_category, product_price_with_vat)
VALUES (:SHOP, :ID, :NAME, :LINK, :IMAGE, :CATEGORY, :PRICE)";
$stmt = $dbh->prepare($sql);
$params = array(
"SHOP" => $xml->getName(),
"ID" => $data->id ,
"NAME" => $data->name,
"LINK" => $data->link,
"IMAGE" => $data->image,
"CATEGORY" => $data->category,
"PRICE" => $data->price_with_vat
);
$stmt->execute($params);
}
//Close Connection
$dbh = null;
} catch(PDOException $e) {
echo $e->getMessage();
}
?>
Site Note:
Add error reporting to the top of your file(s) which will help during production testing.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
?>
Also if you want to show/see the data in html you can use this:
<?php
//Xml stuff
$xml = simplexml_load_file("file.xml");
echo "<table border='1'>";
echo "<tr>
<td>Shop</td>
<td>Product ID</td>
<td>Product Name</td>
<td>Product Link</td>
<td>Product Image</td>
<td>Product Category</td>
<td>Product Price with vat</td>
</tr>";
foreach($xml->products->product as $data) {
echo "<tr>
<td>" . $xml->getName() . "</td>
<td>" . $data->id . "</td>
<td>" . $data->name . "</td>
<td>" . $data->link . "</td>
<td>" . $data->image . "</td>
<td>" . $data->category . "</td>
<td>" . $data->price_with_vat. "</td>
</tr>";
}
echo "</table>";
?>
You are not able to get data because of missing or invalid parent node.
While working with XML needs to handle parent and child(children) node
relationship carefully. Unfortunately you have missed the exact same
thing.
When you use mywebstore node as a parent then its intermediate child node is products and products child node is product.
But when you use products node as a parent then its child node is product.
In your code you have handled the second condition. You have to handle the both conditions or you can use the first condition in your code.
Example:
<?php
$file = 'test.xml';
$xml = simplexml_load_file($file, null, LIBXML_NOCDATA);
if($xml === false){
echo "Failed to load '$file'.\n";
}else{
$productsArr = Array();
if(isset($xml->products)){
$productsArr = $xml->products;
}else if(isset($xml->product)){
$productsArr = $xml;
}
if(sizeof($productsArr) > 0){
foreach($productsArr->product as $productArr){
$productArr = (array) $productArr;
$id = null;
if(isset($productArr['#attributes'])){
$id = $productArr['#attributes']['id'];
unset($productArr['#attributes']);
}
if(!isset($productArr['id']) && !empty($id)){
$productArr['id'] = $id;
}
array_walk_recursive($productArr, function (&$value) {
$value = htmlentities($value,ENT_QUOTES,'UTF-8');
$value = mysql_real_escape_string($value);
});
$col = '`'. implode('`,`',array_keys($productArr)) .'`';
$val = "'". implode("','",array_values($productArr))."'";
$query = "INSERT INTO projectx ($col) VALUES ($val)";
echo "$query \n";
mysql_query($query);
}
}else{
echo "Invalid XML Format.Missing parent node '<mywebstore> or <products>'. \n";
}
}
XML:
Format with <mywebstore> as parent node XML with attribute ID:
`
<?xml version="1.0" encoding="UTF-8"?>
<mywebstore>
<created_at>2010-04-08 12:32</created_at>
<products>
<product id="322233">
<name><![CDATA[MadBiker' 600]]></name>
<link><![CDATA[http://www.mywebstore.co.uk/product/322233]]></link>
<image><![CDATA[http://www.mywebstore.co.uk/product/322233.jpg]]></image>
<category><![CDATA[Outdor > Extreme Sports]]></category>
<price_with_vat>322.33</price_with_vat>
</product>
<product>
<id>322234</id>
<name><![CDATA[MadBiker 700]]></name>
<link><![CDATA[http://www.mywebstore.co.uk/product/322233]]></link>
<image><![CDATA[http://www.mywebstore.co.uk/product/322233.jpg]]></image>
<category><![CDATA[Outdor > Extreme Sports]]></category>
<price_with_vat>344.00</price_with_vat>
</product>
</products>
</mywebstore>
Format with <mywebstore> as parent node XML without attribute ID (Same as Question XML):
`
<?xml version="1.0" encoding="UTF-8"?>
<mywebstore>
<created_at>2010-04-08 12:32</created_at>
<products>
<product>
<id>322233</id>
<name><![CDATA[MadBiker 600]]></name>
<link><![CDATA[http://www.mywebstore.co.uk/product/322233]]></link>
<image><![CDATA[http://www.mywebstore.co.uk/product/322233.jpg]]></image>
<category><![CDATA[Outdor > Extreme Sports]]></category>
<price_with_vat>322.33</price_with_vat>
</product>
</products>
</mywebstore>
`
Format with <products> as parent node XML with attribute ID:
`
<?xml version="1.0" encoding="UTF-8"?>
<products>
<product id="322233">
<name><![CDATA[MadBiker' 600]]></name>
<link><![CDATA[http://www.mywebstore.co.uk/product/322233]]></link>
<image><![CDATA[http://www.mywebstore.co.uk/product/322233.jpg]]></image>
<category><![CDATA[Outdor > Extreme Sports]]></category>
<price_with_vat>322.33</price_with_vat>
</product>
<product>
<id>322234</id>
<name><![CDATA[MadBiker 700]]></name>
<link><![CDATA[http://www.mywebstore.co.uk/product/322233]]></link>
<image><![CDATA[http://www.mywebstore.co.uk/product/322233.jpg]]></image>
<category><![CDATA[Outdor > Extreme Sports]]></category>
<price_with_vat>344.00</price_with_vat>
</product>
</products>
`
Format with <products> as parent node XML without attribute(ID):
`
<?xml version="1.0" encoding="UTF-8"?>
<products>
<product>
<id>322233</id>
<name><![CDATA[MadBiker 600]]></name>
<link><![CDATA[http://www.mywebstore.co.uk/product/322233]]></link>
<image><![CDATA[http://www.mywebstore.co.uk/product/322233.jpg]]></image>
<category><![CDATA[Outdor > Extreme Sports]]></category>
<price_with_vat>322.33</price_with_vat>
</product>
</products>
Conclusion: In valid handling of parents & child node relationship.
Simply change this:
foreach($xml->product as $product)
{
with this:
foreach($xml->products[0] as $product)
{
In order to get the different products you should use xpath
Code:
$xml = simplexml_load_file("xml.xml");
// will search for array of products no matter what it is nested inside of
$products = $xml->xpath('//product');
foreach($products as $product)
{
$columns = array();
$data = array();
foreach($product->children() as $child)
{
echo $child->getName() . ": " . $child . "<br />";
$columns[] = $child->getName();
$data[] = mysql_real_escape_string((string)$child);
}
$col = '`'. implode('`,`',$columns) .'`';
$val = "'". implode("','",$data)."'";
$query = "INSERT INTO XML_FEED ($col) VALUES ($val)";
echo $query;
mysql_query($query);
}
Explanation:
Xpath for simplexml simply returns an array of the simple xml objects or here the product xml elements.
Since we want to return an array of all the products, we search "foreach" occurrence of the product using xpath.
Inside of the xpath string, A double slash (//) signals that all elements in the XML document that match the search criteria are returned, regardless of location/level within the document.
Firstly, simplexml_load_file() returns a pointer to the root element of the XML feed, i.e. the very first XML tag in the input file. In other words, when you write:
$xml = simplexml_load_file("test.xml");
if test.xml contains "<mywebstore> <products> <product> (...)" then $xml points at <mywebstore>
if test.xml contains "<products> <product> (...)" then $xml points at <products>
Secondly, $xml->[tagName] looks for direct children only, not recursively. Therefore $xml->product finds something only if a <product> tag exists as a child of the root element.
In general, it is better for the code to match the input structure exactly. Adapt your outer loop to the expected input:
foreach($xml->product as $product) {
...
}
or
foreach($xml->products->product as $product) {
...
}
If for some reason the <products> tag can be at various locations in the input XML feed, perhaps proceed in two steps:
// try to locate the <product> nodes
if (count($xml->product) !== 0) {
$productNodes = $xml->product;
} else if (count($xml->products->product) !== 0) {
$productNodes = $xml->products->product;
} else {
throw new Exception('No <product> node found');
}
// do the job
foreach($productNodes as $product){
...
}
Or for extreme flexibility, use an xpath. The below will return a list of all <product> nodes anywhere in the XML feed.
$productNodes = $xml->xpath('//product');
foreach($productNodes as $product){
...
}
I trust the MySQL part is not an issue, so I will just stick to the usual incantation:
Please, don't use mysql_* functions in new code. They are no longer maintained and are officially deprecated. See the red box? Learn about prepared statements instead, and use PDO or MySQLi - this article will help you decide which. If you choose PDO, here is a good tutorial.

How to load all xml:lang attributes with SimpleXML

How to read ALL atribute xml:lang values?
Sometimes I do not know how many languages are defined in XMLs data.
<?xml version="1.0" encoding="UTF-8"?>
<offer>
<products>
<product>
<description>
<name xml:lang="eng">English translation</name>
<name xml:lang="lat">Latvian translation</name>
</description>
</product>
<product>
<description>
<name xml:lang="eng">The same English</name>
<name xml:lang="pol">And Polish language</name>
</description>
</product>
</products>
</offer>
I can xml:lang parse in PHP by adding exact language code in xpath
print_r($xml->xpath('products/product/description/name[#xml:lang = "eng"]'));
But I need to add all xml:lang atributes values to parsed array.
Can it be done with PHP SimpleXML?
what about this:
$nodes = $xml->xpath('products/product/description/name[#xml:lang]');
Will return an array of <name>-nodes.
If this is not it, please clarify exactly your desired result.
EDIT
try this to get the xml:lang attributes only:
$langs = $xml->xpath("products/product/description/name[#xml:lang]/#xml:lang");
// $lang is an array of simplexml-elements, transform the values to string like this:
$langs = array_map("strval", $langs);
I'm not 100% on SimpleXML sorry, but I know DomDocument can do what you are after. Hopefully this can be of use to you:
$xmlstring = '<?xml version="1.0" encoding="UTF-8"?>
<offer>
<products>
<product>
<description>
<name xml:lang="eng">English translation</name>
<name xml:lang="lat">Latvian translation</name>
</description>
</product>
<product>
<description>
<name xml:lang="eng">The same English</name>
<name xml:lang="pol">And Polish language</name>
</description>
</product>
</products>
</offer>';
$dom = new DOMDocument();
$dom->loadXML($xmlstring); //or $dom->load('filename.xml');
$xpath = new DOMXPath($dom);
$nodes = $xpath->query('//products/product/description/name');
foreach ($nodes as $node) {
echo 'Language: ' . $node->getAttribute('xml:lang') . '<br />';
echo 'Value: ' . $node->nodeValue . '<br /><br />';
}
You can assign $node->getAttribute('xml:lang') to a variable and run some checks to see if it matches 'eng' or whatever you need.
I used xpath as you had in your original post, but you can also use $dom->getElementsByTagName('name') and access values and attributes in much the same way.
I found easier way to access namespaced attributes. You could use $name->attributes("xml", true) function.
Here is working example:
<?php
$xmlString = '
<products>
<product>
<name xml:lang="eng">
Apples
</name>
<name xml:lang="fr">
Pommes
</name>
</product>
<product>
<name xml:lang="eng">
Strawberries
</name>
<name xml:lang="fr">
Fraises
</name>
</product>
</products>
';
$xml = new \SimpleXMLElement($xmlString);
foreach($xml->product as $product)
{
foreach ($product->name as $name)
{
$attributes = $name->attributes("xml", true);
// print_r($attributes);
foreach ($attributes as $attributeName => $attributeValue)
{
// echo $attributeName . PHP_EOL;
// echo $attributeValue . PHP_EOL;
if ($attributeValue == "eng" && $attributeName == "lang") {
echo "English: " . trim(((string) $name)) . PHP_EOL;
}
if ($attributeValue == "fr" && $attributeName == "lang") {
echo "French: " . trim(((string) $name)) . PHP_EOL;
}
}
}
}
Online demo: https://repl.it/repls/LovingFineDaemon

How do I get to read all the products from XML

I have many categories in my XML file. How can I read all the products in it?
It only reads the first category.
I am including the xml file for you to look at. Here is the PHP code I'm using:
//get products from xml file
foreach($xml->CREATED->CATEGORY as $product){
$atts = $product->PRODUCT->attributes();
$productitemid = $atts['ITEM'];
$title = $product->MODEL;
$rrp = $product->RRP;
$productsdescription = $product->DESCRIPTION;
$prodname = $product->NAME;
echo $productitemid.' - ' ;
// echo $product->id.' - ';
mysql_query("INSERT INTO products (products_id,products_model,products_price,products_status) VALUES ('$productitemid','$title','$rrp','1')");
mysql_query("INSERT INTO products_description (products_id,products_name,products_description) VALUES ('$productitemid','$prodname','$productsdescription')");
}
And here is the XML structure:
<?xml version="1.0" encoding="iso-8859-1"?>
<STOREITEMS>
<CREATED value="Fri Feb 22 1:01:02 GMT 2013">
<CATEGORY id="441" name=" > test1">
<PRODUCT ITEM="12796">
<NAME>test1</NAME>
<MODEL>bb2018</MODEL>
<PRICE>2.28</PRICE>
<RRP>3.99</RRP>
<THUMB>bb2018s.jpg</THUMB>
<IMAGE>bb2018.jpg</IMAGE>
<DESCRIPTION>
test1
</DESCRIPTION>
<POWER/>
<SIZE/>
<ATTRIBUTES NAME="Size" ATTRIBUTEID="2">
<ATTRIBUTEVALUES VALUE="16" TITLE="Small" PRICEADJUST="0.00"/>
<ATTRIBUTEVALUES VALUE="17" TITLE="Medium" PRICEADJUST="0.00"/>
<ATTRIBUTEVALUES VALUE="18" TITLE="Large" PRICEADJUST="0.00"/>
</ATTRIBUTES>
</PRODUCT>
<CATEGORY id="442" name=" > test2">
<PRODUCT ITEM="12805">
<NAME>test2</NAME>
<MODEL>bb2034</MODEL>
<PRICE>0.58</PRICE>
<RRP>1.50</RRP>
<THUMB>bb2034s.jpg</THUMB>
<IMAGE>bb2034.jpg</IMAGE>
<DESCRIPTION>
test2
</DESCRIPTION>
<POWER/>
<SIZE/>
</PRODUCT>
<CATEGORY id="4423" name=" > test3">
<PRODUCT ITEM="13719">
<NAME>test3?</NAME>
<MODEL>BCPG02</MODEL>
<PRICE>2.83</PRICE>
<RRP>4.95</RRP>
<THUMB>bcg02s.jpg</THUMB>
<IMAGE>bcpg02.jpg</IMAGE>
<DESCRIPTION>
test3
</DESCRIPTION>
</PRODUCT>
</CATEGORY>
</CREATED>
</STOREITEMS>
i have done it like this it works. How do i get the products from the categorys then go to the next cateory and get the next porducts the dabase needs them sequence
//i have done it like this it works
$doc = new DOMDocument();
$var = $doc->load('shop.xml');
$root = $doc->documentElement; //root node
$items = $doc->getElementsByTagName('PRODUCT');
$cat = $doc->getElementsByTagName('CATEGORY');
foreach ($cat as $cats){
foreach ($items as $bar)
if ($categoriesid == $b)
$productsid = $bar->getAttribute('ITEM');
$modelcode = $bar->getElementsByTagName('MODEL')->item(0)->nodeValue;
$rrp = $bar->getElementsByTagName('RRP')->item(0)->nodeValue;
$productsdescription = $bar->getElementsByTagName('DESCRIPTION')->item(0)->nodeValue;
$prodname = $bar->getElementsByTagName('NAME')->item(0)->nodeValue;
$categoriesid = $cats->getAttribute('id');
$categoriesname = $cats->getAttribute('name');
}
You could try using DOMDocument like this:
$doc = new DOMDocument();
$var = $doc->load('yourxml.xml');
$root = $doc->documentElement; //root node
$items = $doc->getElementsByTagName('product');
foreach ($items as $bar)
{
$name = $bar->getElementsByTagName('name')->item(0)->nodeValue;
$model = $bar->getElementsByTagName('model')->item(0)->nodeValue;
$price = ....
//do something with the values
}
Please take look on below sample piece of code
hope this help you.
<?php
$xmlString= '<xml Version="1.0">
<created>
<category>
<product id="a"/>
</category>
<category>
<product id="b"/>
</category>
<category>
<product id="c"/>
</category>
<category>
<product id="d"/>
</category>
</created>
</xml>';
$xml = new SimpleXMLElement($xmlString);
foreach ($xml->created->category as $element)
{
foreach($element as $val)
{
echo " product : ".$val->attributes();
}
}
?>
Output of this code will read all product attribute
product : a product : b product : c product : d

PHP access XML node element

I am trying to edit some XML with PHP. Currently the XML looking something like:
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Main Title</title>
<link>http://exmaple.com</link>
<description> blahblahblah </description>
<language>en</language>
<item>
<title>Tite1</title>
<link>http://www.example.com (THIS IS WHAT I WANT)</link>
<description>blah blah blah</description>
</item>
.
.
.
</channel>
</rss>
I've tried to access the 2nd level link but my code only changes the first Link node value. Here is the code:
$xml->load('http://www.google.com/doodles/doodles.xml');
$element = $xml->getElementsByTagName('channel')->item(0);
$secondlvl = $element->getElementsByTagName('item')->item(0);
$2ndlevellinknode = $element->getElementsByTagName('link')->item(0);
$2ndlevellinknode->nodeValue = $newvalue;
Any suggestions? Also is it possible to use this line of code in a for loop like this
for ($i = 0; $i <= 20; $i++) {
$element = $xml->getElementsByTagName('channel')->item(0);
$secondlvl = $element->getElementsByTagName('item')->item(0);
$2ndlevellinknode = $element->getElementsByTagName('link')->item($i);
$2ndlevellinknode->nodeValue = $newvalue;
}
this should give you an idea.
$f = simplexml_load_file('test.xml');
print $f->channel->title . "\n";
print $f->channel->link . "\n";
print $f->channel->description . "\n";
foreach($f->channel->item as $item) {
print $item->title . "\n";
}

Categories