问题
Portion of xml file that represents the problem (the xml file has hundreds of customers record)
<?xml version="1.0" encoding="utf-8"?>
<test>
<customer>
<name>customer 1</name>
<address>address 1</address>
<city>city 1</city>
<state>state 1</state>
<zip>zip 1</zip>
<phone>phone 1</phone>
<buyerinfo>
<shippingaddress>
<name>ship to</name>
<address>Ship address1</address>
</shippingaddress>
</buyerinfo>
<shippingDetail>
<saletax>
<saletaxamount>2</saletaxamount>
</saletax>
</shippingDetail>
</customer>...
Below is my code
//Xml string is parsed and creates a DOM Document object
$responseDoc = new DomDocument();
$responseDoc->load('test.xml');
foreach ($responseDoc->getElementsByTagName('customer') as $customer){
$sSQL = sprintf(
"INSERT INTO customer (name, address, city, state, zip, phone, shipto, shipadderss, tax)
VALUES ('%s','%s', '%s', '%s','%s','%s', '%s','%s','%s')",
mysql_real_escape_string($customer->getElementsByTagName('name')->item(0)->nodeValue),
mysql_real_escape_string($customer->getElementsByTagName('address')->item(0)->nodeValue),
mysql_real_escape_string($customer->getElementsByTagName('city')->item(0)->nodeValue),
mysql_real_escape_string($customer->getElementsByTagName('state')->item(0)->nodeValue),
mysql_real_escape_string($customer->getElementsByTagName('zip')->item(0)->nodeValue),
mysql_real_escape_string($customer->getElementsByTagName('phone')->item(0)->nodeValue)
?
?
?
);
$rResult = mysql_query($sSQL);
if(mysql_errno() > 0)
{
printf(
'<h4 style="color: red;">Query Error:</h4>
<p>(%s) - %s</p>
<p>Query: %s</p>
<hr />',
mysql_errno(),
mysql_error(),
$sSQL
);
}
}
Questions:
How do I get access to get customer.buyerinfo.shippingaddress.name node value using mysql_real_escape_string in my insert statement? indicated with "???"
The fact that I have two nodes with the same node name "name", one is customer.name and another is customer.buyerinfo.shippingaddress.name to name make it problematic to use getElementsByTagName "name" tag to get the value.
the same as the first one but how do I get saletaxamount node data value?
Please kindly help. Thank you!
回答1:
For the XML data you have I would prefer the SimpleXML extension, it ships with everything you need and it's not that much code to write (it is DOMDocument's little sister).
So for each customer in the input data, you want to fetch your 9 or so values. You can formulate those values as an xpath:
$values = <<<XPATH
(
name
|address
|city
|state
|zip
|phone
|buyerinfo/shippingaddress/name
|buyerinfo/shippingaddress/address
|shippingDetail/saletax/saletaxamount
)
XPATH;
This works similar to as with a database query. You create a string that contains the query, for XML in the Xpath language.
And we do same for SQL as both should go hand-in-hand together, so here is is the according SQL pattern:
$pattern = <<<SQL
INSERT INTO customer
(
name, address, city, state, zip, phone, shipto, shipadderss, tax
)
VALUES
(
'%s','%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'
)
SQL;
All this needs now is to open the XML and specify the customer elements to work on:
$customers = simplexml_load_string($test)->customer; // "test.xml"
Then you only need to foreach over each customer, obtain the values, escape them, insert them into the query and run the SQL query (or create one larger query containing more than one record):
foreach ($customers as $customer)
{
$data = $customer->xpath($values);
$escaped = array_map('mysql_real_escape_string', $data);
$query = vsprintf($pattern, $escaped);
// you can now run the query now
// ...
}
Yes, that is your code already. As you can see, Making use of arrays, xpath and SQL, you can simplify this to a great extend.
For the first customer in your sample-XML this then generates the following query:
INSERT INTO customer
(
name, address, city, state, zip, phone, shipto, shipadderss, tax
)
VALUES
(
'customer 1','address 1', 'city 1', 'state 1', 'zip 1', 'phone 1', 'ship to', 'Ship address1', '2'
)
The whole code-example:
$values = <<<XPATH
(
name
|address
|city
|state
|zip
|phone
|buyerinfo/shippingaddress/name
|buyerinfo/shippingaddress/address
|shippingDetail/saletax/saletaxamount
)
XPATH;
$pattern = <<<SQL
INSERT INTO customer
(
name, address, city, state, zip, phone, shipto, shipadderss, tax
)
VALUES
(
'%s','%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'
)
SQL;
$customers = simplexml_load_string($test)->customer; // "test.xml"
foreach ($customers as $customer)
{
$data = $customer->xpath($values);
$escaped = array_map('mysql_real_escape_string', $data);
$query = vsprintf($pattern, $escaped);
// you can now run the query now
$result = mysql_query($query);
if(mysql_errno())
{
printf(
'<h4 style="color: red;">Query Error:</h4>
<p>(%s) - %s</p>
<p>Query:
<pre>%s</pre>
</p>
<hr />',
mysql_errno(),
htmlspecialchars(mysql_error()),
htmlspecialchars($query)
);
}
}
回答2:
you can get child node value with a loop inside shippingaddress
node.
Something like, after
mysql_real_escape_string($customer->getElementsByTagName('phone')->item(0)->nodeValue)
add:
foreach ($customer->getElementsByTagName('buyerinfo') as $buyerinfo)
{
foreach ($buyerinfo->getElementsByTagName('shippingaddress') as $shippingaddress)
{
mysql_real_escape_string($shippingaddress->getElementsByTagName('name')->item(0)->nodeValue),
mysql_real_escape_string($shippingaddress->getElementsByTagName('address')->item(0)->nodeValue)
}
}
of course you will have to fix query with new values.
this should your job, sorry i haven't a chance to test it
来源:https://stackoverflow.com/questions/15976852/insert-xml-data-into-mysql-with-php