在PHP中阅读这个XML结构
问题描述:
<?xml version="1.0"?>
<order>
<order_businessid>2</order_businessid>
<order_categoryid>3</order_categoryid>
<product_id>1</product_id>
<product_name1>CreamCheese Cake</product_name1>
<product_price1>4.10</product_price1>
<product_Qty1>1</product_Qty1>
<product_id>3</product_id>
<product_name2>Gujarati unlimited</product_name2>
<product_price2>50.00</product_price2>
<product_Qty2>1</product_Qty2>
<product_id>5</product_id>
<product_name3>Cheese French Frish</product_name3>
<product_price3>4.10</product_price3>
<product_Qty3>1</product_Qty3>
</order>
如何读取这个结构?在PHP中阅读这个XML结构
我想在PHP中输出:
ProduktID 1, has name CreamCheese Cake and it's price is 4.10
ProduktID 3, has name Gujarati unlimited and it's price is 50.00
等..
我知道如何通过元素做到这一点,如果所有信息是一个元素里面,然后我只想循环,获取属性和输出。
但是有了这个,我不知道在所有的,所以希望你能帮助我..
答
XML的结构非常差 - 使订单上的每个产品都具有正确的结构将使这变得更容易。
但这个工作(使用SimpleXML):
$myxml = '<?xml version="1.0"?>
<order>
<order_businessid>2</order_businessid>
<order_categoryid>3</order_categoryid>
<product_id>1</product_id>
<product_name1>CreamCheese Cake</product_name1>
<product_price1>4.10</product_price1>
<product_Qty1>1</product_Qty1>
<product_id>3</product_id>
<product_name2>Gujarati unlimited</product_name2>
<product_price2>50.00</product_price2>
<product_Qty2>1</product_Qty2>
<product_id>5</product_id>
<product_name3>Cheese French Frish</product_name3>
<product_price3>4.10</product_price3>
<product_Qty3>1</product_Qty3>
</order>';
$xml = simplexml_load_string($myxml);
$count=1;
foreach ($xml->product_id as $prod) {
$pn = $xml->xpath('/order/product_name'.$count);
$price = $xml->xpath('/order/product_price'.$count);
$pq = $xml->xpath('/order/product_Qty'.$count);
echo "ProduktID $prod, has name $pn[0] and it's price is $price[0] and exists $pq[0] time(s)".PHP_EOL;
$count++;
}
答
埃姆...说实话?有开发人员称这是一个XML结构? xD
有几种方法来处理这种废话。我喜欢的正则表达式:
这应该符合你的要求:
/.*?<product_id>(.*?)<\/product_id>.*?<product_name\d*>(.*?)<\/product_name\d*>.*?<product_price\d*>(.*?)<\/product_price\d*>.*?<product_Qty\d*>(.*?)<\/product_Qty\d*>.*/s
和
ProduktID $1, has name $2 and it's price is $3 and exists $4 time(s).\n
这应该与preg_match_all工作,但它是未经测试!
此致敬礼!
+0
我同意你的意见,但我无能为力。 XML结构是由应用程序开发人员制作的 – Karem 2011-12-23 12:39:51
答
下面是使用DOMDocument
一个解决方案:
$doc = new DOMDocument();
$doc->load("order.xml");
$productList = array();
foreach($doc->documentElement->childNodes as $node) {
if($node->tagName == "product_id") {
$productList[] = array(
"id" => $node->textContent,
);
}
if(preg_match("/product_([A-Za-z_]+)(\d+)/", $node->tagName, $m)) {
$productList[$m[2] - 1][$m[1]] = $node->textContent;
}
}
foreach($productList as $product) {
echo "ProduktID ", $product["id"]
, ", has name ", $product["name"]
, " and it's price is ", $product["price"]
, " with quantity ", $product["Qty"]
, "\n";
}
当然,这XML看起来非常奇怪的(所以我分享@阿明的情绪)。它看起来像是“手工制作的”,没有那些奇特的XML工具/库中的一个,而是使用字符串连接或仅使用echo
进行渲染。
答
这将解决你的问题,但我不会喜欢这种XML格式
$xmlStr = '<?xml version="1.0"?>
<order>
<order_businessid>2</order_businessid>
<order_categoryid>3</order_categoryid>
<product_id>1</product_id>
<product_name1>CreamCheese Cake</product_name1>
<product_price1>4.10</product_price1>
<product_Qty1>1</product_Qty1>
<product_id>3</product_id>
<product_name2>Gujarati unlimited</product_name2>
<product_price2>50.00</product_price2>
<product_Qty2>1</product_Qty2>
<product_id>5</product_id>
<product_name3>Cheese French Frish</product_name3>
<product_price3>4.10</product_price3>
<product_Qty3>1</product_Qty3>
</order>';
$xml = simplexml_load_string($xmlStr);
$pid = $pnam = $ppric = '';
foreach($xml as $ky=>$node) {
$pid = ($ky == 'product_id') ? $node[0] : $pid ;
$pnam = (strpos($ky, 'product_name') === 0) ? $node[0] : $pnam;
$ppric = (strpos($ky, 'product_price') === 0) ? $node[0] : $ppric;
if(strpos($ky, 'product_price') === 0) {
echo "product id $pid has name $pnam and its price is $ppric <br>";
}
}
这是一些很糟糕XML。使用相同的名称和组合元素。不要举例,product_name3?只需使用名称,并将所有产品数据作为单个产品元素下的元素/属性进行分组。 – 2011-12-23 15:03:22
这样的XML来自开发人员,他们使用字符串创建XML,而不是DOM方法。只是因为它里面有标签并没有使它成为XML。 – 2011-12-23 15:05:03