My XML is as follows
<?xml version="1.0"?>
<Customers>
<customer>
<custID>
1001
</custID>
<fname>
Lama
</fname>
<lname>
Lai
</lname>
<email>
test#hotmail.com
</email>
<password>
qwer
</password>
</customer>
</Customers>
My php code is as follows:
$xmldoc = new DOMDocument();
$xmldoc->load ("../../data/customer.xml");
$customer = $xmldoc->getElementsByTagName("customer");
and the part to save the detail is as follows:
$customerNew = $xmldoc->createElement("customer");
//$customersTAB = $xmldoc->Customers();
//$customerTAB->appendChild($customerNew);
$customerNewFN = $xmldoc->createElement("fname");
$customerNewFNNode = $xmldoc->createTextNode($firstname);
$customerNewFNNode = $customerNewFN->appendChild($customerNewFNNode);
$customerNewFN = $customerNew->appendChild($customerNewFN);
$customerNewLN = $xmldoc->createElement("lname");
$customerNewLNNode = $xmldoc->createTextNode($lastname);
$customerNewLNNode = $customerNewLN->appendChild($customerNewLNNode);
$customerNewLN = $customerNew->appendChild($customerNewLN);
$customerNewEmail = $xmldoc->createElement("email");
$customerNewEmailNode = $xmldoc->createTextNode($email);
$customerNewEmailNode = $customerNewEmail->appendChild($customerNewEmailNode);
$customerNewEmail = $customerNew->appendChild($customerNewEmail);
$customerNewPass = $xmldoc->createElement("password");
$customerNewPassNode = $xmldoc->createTextNode($password);
$customerNewPassNode = $customerNewPass->appendChild($customerNewPassNode);
$customerNewPass = $customerNew->appendChild($customerNewPass);
$customerNew = $xmldoc->fir appendChild($customerNew);
$xmldoc->save('../../data/sample.xml');
I'm trying to create a completely new customer node INSIDe the Customers node. I can't seem to do that. I've pretty sure I've got the inner nodes properly mapped out but I can seemed to append as another child of Customers node.
The overall result should look like this:
<?xml version="1.0"?>
<Customers>
<customer>
<custID>
1001
</custID>
<fname>
Lama
</fname>
<lname>
Lai
</lname>
<email>
test#hotmail.com
</email>
<password>
qwer
</password>
</customer>
<customer>
<custID>
1002
</custID>
<fname>
Lama2
</fname>
<lname>
Lai2
</lname>
<email>
test2#hotmail.com
</email>
<password>
qwer2
</password>
</customer>
</Customers>
What you could do is first get the <customer> elements and then get the first one to be able to get the parent.
$customer = $xmldoc->getElementsByTagName("customer");
The variable $customer is a DOMNodeList
You can get the first item from that list using $customer->item(0), then get the parentNode (which will be <Customers> and then use insertBefore to insert your new element:
$customer->item(0)->parentNode->insertBefore($customerNew);
Demo
Related
my xml is structured as follow:
<?xml version="1.0" ?>
<user>
<name>
foo
</name>
<token>
jfhsjfhksdjfhsjkfhksjfsdk
</token>
<connection>
<host>
localhost
</host>
<username>
root
</username>
<dbName>
Test
</dbName>
<dbPass>
123456789
</dbPass>
</connection>
</user>
<user>
... same structure...
</user>
I made this code that iterate through all xml node:
function getConString($node)
{
$item = file_get_contents($_SERVER['DOCUMENT_ROOT'] . "con");
$nodes = new SimpleXMLElement($item);
$result = $nodes[0];
foreach($result as $item => $value)
{
if($item == "token")
{
return $value->__toString();
}
}
}
what I'm trying to achieve is that when $node is equal to:
jfhsjfhksdjfhsjkfhksjfsdk
the connection node is returned as array, how I can achieve this?
If the XML you're trying to parse is what you've posted here, it's invalid since
XML documents must contain one root element that is the parent of all other elements:
http://www.w3schools.com/xml/xml_syntax.asp
(and yours doesn't, and parsing such string fails with Exception: String could not be parsed as XML in ...).
So your XML should be:
<?xml version="1.0" ?>
<users>
<user>
<name>
foo
</name>
<token>
jfhsjfhksdjfhsjkfhksjfsdk
</token>
<connection>
<host>
localhost
</host>
<username>
root
</username>
<dbName>
Test
</dbName>
<dbPass>
123456789
</dbPass>
</connection>
</user>
<user>
... same structure...
</user>
</users>
And you don't need to iterate through the collection
// $nodes is SimpleXMLElement
$user = $nodes->user[0];
if($user->token)
return $user->token->__toString();
my XML-file is as follows: agents.xml
<?xml version="1.0" encoding="UTF-8"?>
<agents>
<agent id="1">
<aname>pi1</aname>
<alive>0</alive>
<scenarios>1,2,3</scenarios>
</agent>
<agent id="2">
<aname>pi2</aname>
<alive>1</alive>
<scenarios>4,5,6</scenarios>
</agent>
</agents>
I want to retrieve all child elements of an agent, selected by attribute value "id". I tried the following, passing a the variable "id" to the script:
$agents_xml = simplexml_load_file("/<path_to>/agents.xml");
$json = json_encode($agents_xml);
$array = json_decode($json,TRUE);
//decrement id for correct index
$id=$id-1;
//I want to return in JSON format
$testarr=json_encode($array['agent'][$id]);
echo $testarr;
When "id" has value 1, i got this:
{"#attributes":{"id":"1"},"aname":"pi1","alive":"0","scenarios":"1,2,3"}
But i know, if the XML is disordered like:
<?xml version="1.0" encoding="UTF-8"?>
<agents>
<agent id="2">
<aname>pi2</aname>
<alive>1</alive>
<scenarios>4,5,6</scenarios>
</agent>
<agent id="1">
<aname>pi1</aname>
<alive>0</alive>
<scenarios>1,2,3</scenarios>
</agent>
</agents>
This is not very reliable.
Thanks for any idea!
Try
$str = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<agents>
<agent id="1">
<aname>pi1</aname>
<alive>0</alive>
<scenarios>1,2,3</scenarios>
</agent>
<agent id="2">
<aname>pi2</aname>
<alive>1</alive>
<scenarios>4,5,6</scenarios>
</agent>
</agents>
XML;
$xml = new SimpleXMLElement($str);
foreach($xml->agent as $agent)
{
var_dump($agent);
echo "<hr>";
}
I have the following XML documment:
<list>
<person>
<name>Simple name</name>
</person>
</list>
I try to read it, and basically create another "person" element. The output I want to achieve is:
<list>
<person>
<name>Simple name</name>
</person>
<person>
<name>Simple name again</name>
</person>
</list>
Here is how I am doing it:
$xml = new DOMDocument();
$xml->load('../test.xml');
$list = $xml->getElementsByTagName('list') ;
if ($list->length > 0) {
$person = $xml->createElement("person");
$name = $xml->createElement("name");
$name->nodeValue = 'Simple name again';
$person->appendChild($name);
$list->appendChild($person);
}
$xml->save("../test.xml");
What I am missing here?
Edit: I have translated the tags, so that example would be clearer.
Currently, you're pointing/appending to the node list instead of that found parent node:
$list->appendChild($person);
// ^ DOMNodeList
You should point to the element:
$list->item(0)->appendChild($person);
Sidenote: The text can already put inside the second argument of ->createElement():
$name = $xml->createElement("name", 'Simple name again');
i have this xml file that is being generated by a stock management software i have that i would like to insert it into the Pretashop database. can anybody please help me with this xml file?
<?xml version="1.0" encoding="UTF-8"?>
<Document>
<Products>
<Reference>1101TEST</Reference>
<Valid_internet_product>1</Valid_internet_product>
<Products_name>universal</Products_name>
<Price>69.95</Price>
<Active_product>1</Active_product>
<SupplierNo>08</SupplierNo>
<Weight>5</Weight>
<Description>Koncentreret universalmiddel med salmiak</Description>
<Short_Description>Koncentreret universalmiddel med salmiak</Short_Description>
<MinOrderQty>1</MinOrderQty>
<Categories>
<Category>
<CategoryID>63</CategoryID>
<CategoryName>Bins\Universal</CategoryName>
<Active_category>1</Active_category>
<Changed>0</Changed>
</Category>
</Categories>
<Tax_Class_ID>1</Tax_Class_ID>
<Discount>
<Discount_percentage>percentage</Discount_percentage>
<discountprice_ex_vat>0</discountprice_ex_vat>
<Discountprice_include_vat>0</Discountprice_include_vat>
<Pct_ReductionPercent>0</Pct_ReductionPercent>
</Discount>
</Products>
</Document>
With PrestaShop you can easily import your data using one of these options:
By using the "CSV Import" feature in your Back-office (assuming you also have a .csv export instead of this XML file)
By using the PrestaShop Web-service (custom development required)
By using the existing classes (custom development required)
Below is a quick code snippet that is working with your XML string.
It will create or update all the products, and take into account their price, availability, name, description, weight, etc.
Please note that:
This code will is not designed to work with combinations (color, sizes, etc.)
This code does not create categories for you, and is adding all the products to the "Home" category
This is just an example to assist you ;)
<?php
include(dirname(__FILE__).'/config/config.inc.php');
include(dirname(__FILE__).'/init.php');
$xml_string = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<Document>
<Products>
<Reference>1101TEST</Reference>
<Valid_internet_product>1</Valid_internet_product>
<Products_name>universal</Products_name>
<Price>69.95</Price>
<Active_product>1</Active_product>
<SupplierNo>08</SupplierNo>
<Weight>5</Weight>
<Description>Koncentreret universalmiddel med salmiak</Description>
<Short_Description>Koncentreret universalmiddel med salmiak</Short_Description>
<MinOrderQty>1</MinOrderQty>
<Categories>
<Category>
<CategoryID>63</CategoryID>
<CategoryName>Bins\Universal</CategoryName>
<Active_category>1</Active_category>
<Changed>0</Changed>
</Category>
</Categories>
<Tax_Class_ID>1</Tax_Class_ID>
<Discount>
<Discount_percentage>percentage</Discount_percentage>
<discountprice_ex_vat>0</discountprice_ex_vat>
<Discountprice_include_vat>0</Discountprice_include_vat>
<Pct_ReductionPercent>0</Pct_ReductionPercent>
</Discount>
</Products>
</Document>
XML;
$xml = simplexml_load_string($xml_string);
foreach ($xml->Products as $product_xml)
{
if ($product_xml->Valid_internet_product == 1)
{
/* Update an existing product or Create a new one */
$id_product = (int)Db::getInstance()->getValue('SELECT id_product FROM '._DB_PREFIX_.'product WHERE reference = \''.pSQL($product_xml->Reference).'\'');
$product = $id_product ? new Product((int)$id_product, true) : new Product();
$product->reference = $product_xml->Reference;
$product->price = (float)$product_xml->Price;
$product->active = (int)$product_xml->Active_product;
$product->weight = (float)$product_xml->Weight;
$product->minimal_quantity = (int)$product_xml->MinOrderQty;
$product->id_category_default = 2;
$product->name[1] = utf8_encode($product_xml->Products_name);
$product->description[1] = utf8_encode($product_xml->Description);
$product->description_short[1] = utf8_encode($product_xml->Short_Description);
$product->link_rewrite[1] = Tools::link_rewrite($product_xml->Products_name);
if (!isset($product->date_add) || empty($product->date_add))
$product->date_add = date('Y-m-d H:i:s');
$product->date_upd = date('Y-m-d H:i:s');
$id_product ? $product->updateCategories(array(2)) : $product->addToCategories(array(2));
$product->save();
echo 'Product <b>'.$product->name[1].'</b> '.($id_product ? 'updated' : 'created').'<br />';
}
}
This question already exists:
Closed 10 years ago.
Possible Duplicate:
XML formatting is not working well
I am trying to create an XML file from the database. Database contains name, phone no and sex. I would like to get all the users' details in a well-formatted XML file. But I am getting now:
<CUSTOMERS>
<name>AAA</name>
<name>BBB</name>
</CUSTOMERS>
This is my code:
$xmlstr = "<?xml version='1.0' ?>\n"."<CUSTOMERS></CUSTOMERS>";
$xml = new SimpleXMLElement($xmlstr);
while($b=$result->fetch_assoc()){
$xml->addChild("name", $b['name']);
}
return $xml->asXML();
I would like to get the out put as shows below
<CUSTOMERS>
<AAAA>
<name>AAA</name>
<phone>111</phone>
<sex>male</sex>
</AAA>
<BBBB>
<name>BBB</name>
<phone>222</phone>
<sex>female</sex>
</AAA>
</CUSTOMERS>
Latest Code
$xmlstr = "<?xml version='1.0' ?>\n"."<CUSTOMERS></CUSTOMERS>";
$xml = new SimpleXMLElement($xmlstr);
while($b=$result->fetch_assoc()){
$customer = $xml->addChild("customer");
$customer->addChild("name", $b['name']);
$customer->addChild("phone", $b['phone']);
$customer->addChild("sex", $b['sex']);
//$xml->addChild("place", $b['place']);
}
return $xml->asXML();
Each customer should be in its own tag:
$d = simplexml_load_string('<?xml version="1.0" encoding="utf-8" ?><customers />');
$customer = $d->addChild('customer');
$customer->addChild('name', 'Jack');
// $customer->addChild('phone', '911');
// etc.
$customer = $d->addChild('customer');
$customer->addChild('name', 'John');
echo $d->asXML();
<?xml version="1.0" encoding="utf-8"?>
<customers>
<customer><name>Jack</name></customer>
<customer><name>John</name></customer>
</customers>
Note that the tag name should not be the name of your customer, it should rather be a description of what information is inside; hence my use of the customer tag.
You should be able to do it like this:
$xml = new SimpleXMLElement("<customers></customers>");
while($b=$result->fetch_assoc()){
$customer = $xml->addChild("customer");
$customer->addChild("name", $b['name']);
$customer->addChild("phone", $b['phone']);
$customer->addChild("sex", $b['sex']);
}
Output:
<customers>
<customer>
<name>AAA</name>
<phone>1234567</phone>
<sex>f</sex>
</customer>
</customers>
You are telling PHP to add the <name> child but nothing else.
$xml->addChild("name", $b['name']);
In that while loop, you need to add the <AAA> element, then the child <name>, <phone>, and <sex> (and etc) elements.
The question is to change this
$xmlstr = "<?xml version='1.0' ?>\n"."<CUSTOMERS></CUSTOMERS>";
to this
$xmlstr = = '<' . '?xml version='1.0' ?>\n"."<CUSTOMERS></CUSTOMERS>';
As the <? messes up the parser.
Also XML does not like capitals and needs a root - i.e. something between your customers.