Как отредактировать мой код для сохранения в mySQL с начала XML?

У меня есть этот XML-канал ниже, я пытаюсь импортировать в MySQL для всех продуктов.
Например, внутри таблицы XML_FEED Я хочу что-то вроде

shop        -   product_id - product_name - product_link - .......
mywebstore  -   322233     - MadBiker 600 - .........
mywebstore  -   324633     - Samsung S4 - .........

Код до сих пор работает, только если XML начинается с <products> а не из <mywebstore>

Как изменить мой код, чтобы сделать это?

$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);
}

Вот 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>

-7

Решение

Это должно работать для вас:

<?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();
}

?>

Примечание сайта:

Добавьте отчет об ошибках в начало файла (ов), который поможет во время производственного тестирования.

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
?>

Также, если вы хотите показать / увидеть данные в формате HTML, вы можете использовать это:

<?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>";

?>
0

Другие решения

Используйте этот код:

<?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);
}
?>
1

Вы не можете получить данные из-за отсутствия или неверного родительского узла.

При работе с XML необходимо обрабатывать родительский и дочерний (дочерний) узел
отношения тщательно. К сожалению, вы пропустили то же самое
вещь.

  1. Когда вы используете mywebstore узел в качестве родителя, то его промежуточный дочерний узел товары а также товары дочерний узел товар.
  2. Но когда вы используете товары узел как родительский, то его дочерний узел товар.

В вашем коде вы обработали второе условие. Вы должны обработать оба условия, или вы можете использовать первое условие в вашем коде.

Пример:

<?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:

  1. Форматировать с <mywebstore> как родительский узел XML с идентификатором атрибута:

`

<?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>
  1. Форматировать с <mywebstore> как родительский узел XML без идентификатора атрибута (такой же, как вопрос 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>

`

  1. Форматировать с <products> как родительский узел XML с идентификатором атрибута:

`

<?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>

`

  1. Форматировать с <products> как родительский узел XML без атрибута (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>

Заключение: В правильном обращении с родителями & отношения дочернего узла.

0

Просто измените это:

foreach($xml->product as $product)
{

с этим:

foreach($xml->products[0] as $product)
{
0

Для того, чтобы получить различные продукты, вы должны использовать XPath

Код:

$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);

}

Объяснение:

Xpath для simplexml просто возвращает массив простых xml-объектов или здесь xml-элементов продукта.

Так как мы хотим вернуть массив всех продуктов, мы ищем вхождение «foreach» продукта, используя xpath.

Внутри строки xpath двойная косая черта (//) означает, что возвращаются все элементы в документе XML, которые соответствуют критериям поиска, независимо от местоположения / уровня в документе.

0

Во-первых, simplexml_load_file() возвращает указатель на корень элемент ленты XML, т. е. самый первый тег XML во входном файле. Другими словами, когда вы пишете:

$xml = simplexml_load_file("test.xml");
  • если test.xml содержит «<mywebstore> <products> <product> (...)» затем $xml указывает на <mywebstore>
  • если test.xml содержит «<products> <product> (...)» затем $xml указывает на <products>

Во-вторых, $xml->[tagName] ищет непосредственный только дети, а не рекурсивно. Следовательно $xml->product находит что-то, только если <product> тег существует как дочерний элемент корневого элемента.

В целом, лучше, чтобы код точно соответствовал структуре ввода. Адаптируйте ваш внешний цикл к ожидаемому входу:

foreach($xml->product as $product) {
...
}

или же

foreach($xml->products->product as $product) {
...
}

Если по какой-то причине <products> тег может находиться в разных местах входного XML-канала, возможно, выполнить в два этапа:

// 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){
...
}

Или для чрезвычайной гибкости, используйте xpath. Ниже вернется список всех <product> узлы в любом месте в канале XML.

$productNodes = $xml->xpath('//product');

foreach($productNodes as $product){
...
}

Я верю, что часть MySQL не является проблемой, поэтому я просто придерживаюсь обычного заклинания:

Пожалуйста, не используйте mysql_* функции в новом коде. Они больше не поддерживаются и официально устарели. Увидеть красная коробка? Узнать о готовые заявления вместо этого и использовать PDO или же MySQLiЭта статья поможет вам решить, какой. Если вы выбираете PDO, вот хороший урок.

0
По вопросам рекламы [email protected]