簡體   English   中英

使用SimpleXML和xpath訪問XML節點值

[英]Accessing XML node value using SimpleXML and xpath

這些問題很多,請原諒我。 我看完了

我有以下使用命名空間http://www.columbasystems.com/cpng/xmlviewer/cal/1-0/的 XML文檔: http : //events.manchester.ac.uk/f3vf/calendar/tag : manchester_museum/視圖:列表/ p:q_details / calml.xml

我正在嘗試使用SimpleXML解析此文檔。 下面的示例代碼嘗試從下面訪問標題節點“ Discovery Center”的值。

<ns:calendar xmlns:ns="http://www.columbasystems.com/cpng/xmlviewer/cal/1-0/">
    <ns:listView>
    <ns:day date="2015-07-08" weekDay="Wed">
    <ns:event>
    <ns:id xmlns:even="http://www.columbasystems.com/customers/uom/gpp/eventid/" query="{http://www.columbasystems.com/customers/uom/gpp/eventid/}b9v-ib270yqf-nmn54k">even:b9v-ib270yqf-nmn54k</ns:id>
    <ns:title>Discovery Centre</ns:title>
    ...
</ns:event>
</ns:day>
</ns:listView>
</ns:calendar>

PHP的:

$feed_uri = 'http://events.manchester.ac.uk/f3vf/calendar/tag:manchester_museum/view:list/p:q_details/calml.xml';
$xml = simplexml_load_file($feed_uri);
$xml->registerXPathNamespace("ns", "http://www.columbasystems.com/cpng/xmlviewer/cal/1-0/");

foreach($xml->xpath('//ns:calendar/ns:listView/ns:day') as $day) {
    $events = $day->xpath('//ns:event');
    foreach($events as $event) {
        var_export($event->xpath('//ns:title'));
    }
}

輸出幾個空數組:

array ( 0 => SimpleXMLElement::__set_state(array( )),

我認為我使用xpath錯誤,我如何獲得像這樣的節點的值?

您的輸出不是一個空數組。 空數組如下所示:

array()

但是你有這個:

array ( 0 => SimpleXMLElement::__set_state(array( )),

因此,顯然XPath可以正常工作,並為您提供結果列表(數組)(SimpleXMLElement對象)。

問題在於var_export在檢查SimpleXMLElement對象方面不是很好,因此您看不到實際得到的結果。

要獲取節點的文本內容,必須將其強制轉換為字符串-使用(string)$node顯式轉換,或使用類似echo隱式轉換。 所以下面的工作:

foreach($xml->xpath('//ns:calendar/ns:listView/ns:day') as $day) {
    $events = $day->xpath('//ns:event');
    foreach($events as $event) {
        foreach ($event->xpath('//ns:title') as $title ) {
            echo $title;
        }
    }
}

但是,您的XPath表達式確實存在一個小錯誤(與使用SimpleXML或任何其他API無關): //前綴始終始於文檔的根目錄,而不是用作上下文的元素。 要搜索“當前元素內的任何深度”,您需要.// ,例如$day->xpath('.//ns:event')

就是說,您實際上根本不需要像XPath那樣花哨的東西,因為它沒有那么深的結構。 因此,只要您首先使用->children()方法選擇正確的名稱空間,就可以使用SimpleXML的常規訪問 方法

$cal_items = $xml->children("http://www.columbasystems.com/cpng/xmlviewer/cal/1-0/");

foreach($cal_items->listView->day as $day) {
    foreach($day->event as $event) {
        echo $event->title;
    }
}

請注意,您的XML包含沒有名稱空間前綴的屬性,例如<ns:day date="2015-07-09" weekDay="Thu"> 有點不直觀,它們在官方上根本沒有命名空間 ,因此您必須切換回null命名空間才能訪問它們:

echo $day->attributes(null)['date'];

我將xml放在字符串中,改回文件。 希望其他都清楚

$str = '<ns:calendar xmlns:ns="http://www.columbasystems.com/cpng/xmlviewer/cal/1-0/">
    <ns:listView>
    <ns:day date="2015-07-08" weekDay="Wed">
    <ns:event>
    <ns:id xmlns:even="http://www.columbasystems.com/customers/uom/gpp/eventid/" query="{http://www.columbasystems.com/customers/uom/gpp/eventid/}b9v-ib270yqf-nmn54k">even:b9v-ib270yqf-nmn54k</ns:id>
    <ns:title>Discovery Centre</ns:title>
</ns:event>
</ns:day>
</ns:listView>
</ns:calendar>';

$xml = simplexml_load_string($str);
$xml->registerXPathNamespace("ns", "http://www.columbasystems.com/cpng/xmlviewer/cal/1-0/");

foreach($xml->xpath('//ns:calendar/ns:listView/ns:day') as $day) {
    echo $day['date'] . ' ';
    $events = $day->xpath('.//ns:event');
    foreach($events as $event) {
        echo $event->xpath('.//ns:title/text()')[0];

    }
}

結果

2015-07-08 Discovery Centre

更新您可以使用前綴insead完整URL。 並記住在這種情況下如何獲得屬性值

$cal_items = $xml->children("ns",true);
foreach($cal_items->listView->day as $day) {
    echo $day->attributes()['date'] . ' ' ;
    foreach($day->event as $event) {
        echo $event->title;
    }
}

暫無
暫無

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

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