簡體   English   中英

使用XPATH從XML文件檢索信息的更好方法

[英]Better way of retrieving info from XML file using XPATH

到目前為止,我有一個非常簡單的類,名為Menu.php,其中包含以下內容:

<?php
class Menu
{
    private $_dom;
    private $categoryItems;

    function __construct()
    {
        if(file_exists('Menu.xml'))
        {
            $this->_dom = simplexml_load_file('Menu.xml');
            }

    }

    public function retrieveMenu($category)
    {       
        $products = $this->_dom->xpath('/menu/category[@name="'.$category.'"]');
        return $products;
    }
} // end of class Menu

我知道,很簡單,僅用於測試目的。 現在,我還有一個如下的XML文件:

<?xml version="1.0" encoding="UTF-8" ?>
<menu>

    <category name="pizza">
        <item name="Tomato and Cheese">
            <type>Regular</type>
            <available>true</available>
            <size name="Small">
                <price>5.50</price>
            </size>
            <size name="Large">
                <price>9.75</price>
            </size>
        </item>
    </category>

    <category name="pizza">
        <item name="Pepperoni">
            <type>Regular</type>
            <available>true</available>
            <size name="Small">
                <price>6.85</price>
            </size>
            <size name="Large">
                <price>10.85</price>
            </size>
        </item>
    </category>

這與多種產品有關。 因此,這個想法是通過類訪問此文件,並實現在index.php中執行以下操作:

<?php
require 'Menu.php';
$menu = new Menu();
$tests = $menu->retrieveMenu('pizza');
foreach($tests as $test) {
    echo $test->attributes();
    echo '<br />';
    foreach($test->item as $item) {
        echo $item->attributes();
        echo '<br />';
        echo $item->type;
        echo '<br />';
        echo $item->available;
        echo '<br />';
        foreach($item->size as $price) {
            echo $price->attributes();
            echo '<br />';
            echo $price->price;
            echo '<br />';
            echo '<br />';
            echo $price->price;
            echo '<br />';*/
        }
        //echo $item->size->attributes();
        echo '<br /><br /><br /><br />';
    }
}

這給了我我期望的結果:

>pizza
>Tomato and Cheese
>Regular
>true
>Small
>5.50
>Large
>9.75

現在,我的問題是:由於我沒有錯,所以我使用了3個嵌套的for循環,因此復雜度為n ^ 3,這非常糟糕,原始XML包含許多產品,是否有更好的訪問方法? 難道我做錯了什么?

順便說一句, 是的,我必須使用XML和XPATH

在這種情況下,嵌套循環沒有問題。 您可以訪問並在單個資源上輸出所有子元素。 但是,可以,Xpath可以將不同級別的節點提取到列表中。

Xpath表達式可以使用| 合並多個位置路徑。 因此它實際上是三個位置路徑,並且表達式返回所有匹配的節點:

  1. 所有元素的name屬性節點: //*/@name
  2. item子元素,除了size//item/*[not(self::size)]
  3. price item/size子元素: //item/size/price

本示例使用DOM:

$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);

$expression = '//*/@name|//item/*[not(self::size)]|//item/size/price';

foreach ($xpath->evaluate($expression) as $node) {
  echo trim($node->nodeValue), "<br/>\n"; 
}

輸出:

pizza<br/>
Tomato and Cheese<br/>
Regular<br/>
true<br/>
Small<br/>
5.50<br/>
Large<br/>
9.75<br/>
pizza<br/>
Pepperoni<br/>
Regular<br/>
true<br/>
Small<br/>
6.85<br/>
Large<br/>
10.85<br/>

Xpath中的位置路徑就像一個過濾器一樣工作,節點根據其在文檔中的位置按順序返回。

它也適用於SimpleXML:

$element = simplexml_load_string($xml);

$expression = '//*/@name|//item/*[not(self::size)]|//item/size/price';

foreach ($element->xpath($expression) as $node) {
  echo trim($node), "<br/>\n"; 
}

演示: https : //eval.in/156266

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM