2017-02-15 54 views
0

我有几个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); 
    } 
} 

但这种方式太不稳定了,我想。我想保证两个值都是一对。因为它可能是一种产品不包含价格或标题,这是不可想象的,但它可能是! (该文件不是从我

那么,有没有办法让每个product的标签namepreis在同一时间,作为对 - !?因为这是安全的唯一途径

!问候和感谢!

回答

1

是的,这是。您将DOM转换为SimpleXML以使用Xpath。这不是必需的。 DOM具有DOMXpath类,而DOMXpath::evaluate()更强大,然后SimpleXMLElement::xpath()

Xpath可以做很多事情。例如,你可以取一个具有namepreis任何产品:

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

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

+0

如果你能给我一个simplexml,我会非常感激。 但是除此之外,你能否解释你如何得到价格和名称? - 因为'$ property-> localName'和'$ property-> textContent'不是名字,不是价格? – Jan

+0

我已经更新了答案。你现在有一个simplexml的例子 – motanelu