PHP-尝试显示xml标记(具有相同名称的标记)节点值


PHP - Trying to display xml tag(tags with same name) nodevalue

我正在尝试显示XML文件中的信息。我使用的是PHP及其DOMDocument类。我正在附加我尝试过的xml文件和php代码。

<?xml version="1.0" encoding="utf-8" ?>
<services>
<service>
    <type>Wash</type>
    <title>Wash1</title>
    <content>Full Exterior Hand Wash</content>
    <content>Chamois dry, Pressure Clean Wheels, All Door Jambs</content>   
    <content>Plus Free Typre Gloss</content>
    <price>Hatch/Sedan:$15</price>
    <price>Others:$20</price>
</service>
<service>
    <type>Wash</type>
    <title>Wash2</title>
    <content>Wash1</content>
    <content>Plus Vacuum</content>   
    <content>Glass Cleaned(IN/OUT)</content>
    <content>Plus Free Interior Wipe</content>
    <price>Hatch/Sedan:$30</price>
    <price>Others:$38</price>
 </service>
 </services>

php代码。。。

    <?php
    header('Content-Type: text/html;charset=utf8');
    $xmlfile = new DOMDocument();
    $xmlfile->load('services.xml');
    $services = $xmlfile->getElementsByTagName('service');
    foreach($services as $service){
         $titles = $service->getElementsByTagName('title');
         $title = $titles->item(0)->nodeValue;
         echo "<h1>$title</h1>";
         $prices = $xmlfile->getElementsByTagName('price');
         foreach($prices as $price){
             $price = $prices->item(0)->nodeValue;
             echo "<h1>$price</h1>";
         }
     }
?>

我只是想输出价格标签值,因为如果这有效的话,显示内容应该不会有问题。最终,我将在HTML结构中一个接一个地显示这些值。

谢谢你的帮助。

编辑:此代码此时输出

Wash1
Hatch/Sedan:$15
Hatch/Sedan:$15
Hatch/Sedan:$15
Hatch/Sedan:$15
Wash2
Hatch/Sedan:$15 
Hatch/Sedan:$15
Hatch/Sedan:$15
Hatch/Sedan:$15

这里有两个bug。正如另一个答案所指出的,你从错误的元素中得到$prices

$prices = $xmlfile->getElementsByTagName('price');

应该是:

$prices = $service->getElementsByTagName('price');

然而,这并不能完全解决问题,因为还有另一个问题。你在循环浏览价格,但总是返回第一个<price>。你需要改变这个:

$price = $prices->item(0)->nodeValue;

到此:

$price = $price->nodeValue;

更正后的代码变为:

<?php
header('Content-Type: text/html;charset=utf8');
$xmlfile = new DOMDocument();
$xmlfile->load('services.xml');
$services = $xmlfile->getElementsByTagName('service');
foreach($services as $service){
     $titles = $service->getElementsByTagName('title');
     $title = $titles->item(0)->nodeValue;
     echo "<h1>$title</h1>";
    $prices = $service->getElementsByTagName('price');
    foreach($prices as $price){
        $price = $price->nodeValue;
        echo "<h1>$price</h1>";
    }
}

输出:

洗涤1

哈奇/轿车:$15

其他:$20

洗涤2哈奇/轿车:$30

其它:$38


您已询问何时需要使用item()。这基本上取决于您处理的是一组节点(DOMNodeList(还是单个节点(DOMNode(。getElementsByTagName返回一个DOMNodeList(可能有很多元素(,因此您需要选择一个元素,例如:

 $titles = $service->getElementsByTagName('title'); // Returns a `DOMNodeList` with all the titles
 $title = $titles->item(0)->nodeValue;              // Grabs just the first title

您可以通过DOMNodeList(它实现了Traversable(接口进行迭代。当你迭代时,你会得到一个DOMNode

$prices = $service->getElementsByTagName('price'); // Returns a `DOMNodeList`
foreach ($prices as $price) { // $price is a `DOMNode`
    // ...
}
 $prices = $xmlfile->getElementsByTagName('price');

是错误的-你应该得到$service 的元素

$prices = $service->getElementsByTagName('price');

我不会留下一些代码,但对于xml操作,我更喜欢SimpleXML

在php站点上可以找到一个基本的exmaple

我放了一些代码:

$xmlstr = <<<XML
<?xml version="1.0" encoding="utf-8" ?>
<services>
<service>
    <type>Wash</type>
    <title>Wash1</title>
    <content>Full Exterior Hand Wash</content>
    <content>Chamois dry, Pressure Clean Wheels, All Door Jambs</content>   
    <content>Plus Free Typre Gloss</content>
    <price>Hatch/Sedan:$15</price>
    <price>Others:$20</price>
</service>
<service>
    <type>Wash</type>
    <title>Wash2</title>
    <content>Wash1</content>
    <content>Plus Vacuum</content>   
    <content>Glass Cleaned(IN/OUT)</content>
    <content>Plus Free Interior Wipe</content>
    <price>Hatch/Sedan:$30</price>
    <price>Others:$38</price>
 </service>
 </services>
XML;
$xml = new SimpleXMLElement($xmlstr);
foreach ($xml->service as $key) {
    echo $key->title, "'n";
    foreach ($key->price as $price) {
        echo $price, "'n";
    }
}

输出为:

Wash1
Hatch/Sedan:$15
Others:$20
Wash2
Hatch/Sedan:$30
Others:$38