我有几个XML文件,想要获得每个产品的两个值。我可以这样做:
$doc = simplexml_import_dom($dom);
$items = $doc->xpath("//$tagName");
$titles = array();
$prices = array();
foreach ($items as $item) {
$node = dom_import_simplexml($item);
if(strcasecmp($tagName, "title") == 0){
array_push($titles, $node->textContent);
}
if(strcasecmp($tagName, "price") == 0){
array_push($prices, $node->textContent);
}
}
但我认为这种方式太不稳定了。我希望两个价值形成一对是安全的。因为它可能是一个产品不包含价格或标题,这是不可想象的,但它可能是! (文件不是来自我!
那么有没有办法同时获得每个name
的{{1}}和preis
代码? - 因为这是唯一安全的方法!
问候,谢谢!
答案 0 :(得分:1)
一项建议是使用DOM代替simplexml。我觉得它更有表现力。
---后来编辑---
这是simplexml实现
$string = <<<EOS
<?xml version='1.0' encoding='UTF-8'?>
<products>
<product>
<name>Battlefield 1</name>
<preis>80</preis>
<sterne>3</sterne>
<desc>Dies ist ein Text</desc>
<link>https://www.google.de/</link>
</product>
<product>
<name>Battlefield 2</name>
<preis>180</preis>
<sterne>3</sterne>
<desc>Dies ist ein Text</desc>
<link>https://www.google.de/</link>
</product>
<product>
<name>Battlefield 3</name>
<preis>280</preis>
<sterne>3</sterne>
<desc>Dies ist ein Text</desc>
<link>https://www.google.de/</link>
</product>
<product>
<name>Battlefield 4</name>
<preis>380</preis>
<sterne>3</sterne>
<desc>Dies ist ein Text</desc>
<link>https://www.google.de/</link>
</product>
<product>
<name>Battlefield 5</name>
<preis>480</preis>
<sterne>3</sterne>
<desc>Dies ist ein Text</desc>
<link>https://www.google.de/</link>
</product>
</products>
EOS;
$doc = simplexml_load_string($string);
// get a list of products
$products = $doc->xpath('/products/product');
// iterate of the list
foreach ($products as $product) {
$name = $product->name->__toString();
$price = $product->preis->__toString();
echo $name . ' = ' . $price . PHP_EOL;
}
---后期编辑结束---
这是一个有效的例子:
<?php
$string = <<<EOS
<?xml version='1.0' encoding='UTF-8'?>
<products>
<product>
<name>Battlefield 1</name>
<preis>80</preis>
<sterne>3</sterne>
<desc>Dies ist ein Text</desc>
<link>https://www.google.de/</link>
</product>
<product>
<name>Battlefield 2</name>
<preis>180</preis>
<sterne>3</sterne>
<desc>Dies ist ein Text</desc>
<link>https://www.google.de/</link>
</product>
<product>
<name>Battlefield 3</name>
<preis>280</preis>
<sterne>3</sterne>
<desc>Dies ist ein Text</desc>
<link>https://www.google.de/</link>
</product>
<product>
<name>Battlefield 4</name>
<preis>380</preis>
<sterne>3</sterne>
<desc>Dies ist ein Text</desc>
<link>https://www.google.de/</link>
</product>
<product>
<name>Battlefield 5</name>
<preis>480</preis>
<sterne>3</sterne>
<desc>Dies ist ein Text</desc>
<link>https://www.google.de/</link>
</product>
</products>
EOS;
$doc = new DOMDocument();
$doc->loadXml($string);
$products = $doc->getElementsByTagName('product');
$index = 0;
foreach ($products as $product) {
echo 'Showing information for product #' . $index++ . PHP_EOL;
foreach ($product->childNodes as $property) {
if ($property instanceof DOMText) continue;
echo ' ->' . $property->localName . ' = ' . $property->textContent . PHP_EOL;
}
}
如果您需要simplexml
,请告诉我们答案 1 :(得分:1)
是的,这是。您正在将DOM转换为SimpleXML以使用Xpath。这不是必需的。 DOM具有DOMXpath
类,DOMXpath::evaluate()
比SimpleXMLElement::xpath()
更强大。
Xpath可以做很多事情。例如,您可以获取具有name
和preis
的任何产品:
//product[normalize-string(name) != '' and normalize-string(preis) != '']
但要获得连接的值,您需要获取并迭代product
个节点,然后执行其他Xpath表达式来获取值。
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$result = [];
foreach ($xpath->evaluate('//product') as $product) {
$result[] = [
'title' => $xpath->evaluate('string(name)', $product),
'price' => $xpath->evaluate('number(preis)', $product)
];
}
var_dump($result);
输出:
array(5) {
[0]=>
array(2) {
["title"]=>
string(13) "Battlefield 1"
["price"]=>
float(80)
}
[1]=>
array(2) {
["title"]=>
string(13) "Battlefield 2"
["price"]=>
float(180)
}
...
string(name)
获取所有name
子节点并将结果转换为字符串。在Xpath中,表示返回列表中第一个节点的文本内容。如果列表为空,则会得到一个空字符串。
number(preis)
获取所有preis
个子节点,并将第一个节点的文本内容强制转换为数字。如果此处没有匹配的节点,则结果为0
。