2012-08-02 37 views
0

我在使用PHP的XMLReader類的moveToAttribute方法時遇到問題。
我不想讀取XML文件的每一行。我希望能夠遍歷XML文件,而不必按順序進行;即隨機訪問。我認爲使用moveToAttribute會將光標移動到具有指定屬性值的節點,然後我可以在其內部節點上執行處理,但是這不會按計劃進行。如何使用PHP的XMLReader類中的moveToAttribute方法?

這裏的xml文件的一個片段:

<?xml version="1.0" encoding="Shift-JIS"?> 
    <CDs> 
     <Cat Type="Rock"> 
      <CD> 
       <Name>Elvis Prestley</Name> 
       <Album>Elvis At Sun</Album> 
      </CD> 
      <CD> 
       <Name>Elvis Prestley</Name> 
       <Album>Best Of...</Album> 
      </CD> 
     </Cat> 
     <Cat Type="JazzBlues"> 
      <CD> 
       <Name>B.B. King</Name> 
       <Album>Singin' The Blues</Album> 
      </CD> 
      <CD> 
       <Name>B.B. King</Name> 
       <Album>The Blues</Album> 
      </CD> 
     </Cat> 
    </CDs> 

這裏是我的PHP代碼:

<?php 

    $xml = new XMLReader(); 
    $xml->open("MusicCatalog.xml") or die ("can't open file"); 
    $xml->moveToAttribute("JazzBlues"); 

    print $xml->nodeType . PHP_EOL; // 0 
    print $xml->readString() . PHP_EOL; // blank ("") 
?> 

我在做什麼錯,關於moveToAttribute?我如何使用節點的屬性隨機訪問節點?我想按目標節點Cat Type =「JazzBlues」而不按順序執行(即$ xml-> read()),然後處理其內部節點。

非常感謝。

+1

您可能會更好地使用XML解析器,如SimpleXML與xpath支持http://php.net/manual/en/simplexmlelement.xpath.php – 2012-08-02 15:39:44

+0

是的,我認爲這是一個好主意。我以爲我不需要它,但似乎XMLReader是一個或多個越野車的組合,並沒有很好地記錄(足夠)。 – user717236 2012-08-02 15:54:32

+1

我已經使用SimpleXML很多,它通常與IMO合作很不錯。 – 2012-08-02 16:05:50

回答

0

我認爲沒有辦法避免XMLReader :: read。 XMLreader :: moveToAttribute僅在XMLReader已指向元素時才起作用。此外,您還可以檢查XMLReader :: moveToAttribute的返回值以檢測可能的故障。也許嘗試這樣:

<?php 
$xml = new XMLReader(); 
$xml->open("MusicCatalog.xml") or die ("can't open file"); 
while ($xml->read() && xml->name != "Cat"){ } 
//the parser now found the "Cat"-element 
//(or the end of the file, maybe you should check that) 
//and points to the desired element, so moveToAttribute will work 
if (!$xml->moveToAttribute("Type")){ 
    die("could not find the desired attribute"); 
} 
//now $xml points to the attribute, so you can access the value just by $xml->value 
echo "found a 'cat'-element, its type is " . $xml->value; 
?> 

這段代碼應該打印文件中第一個cat元素的type-attribute的值。我不知道你想用文件做什麼,所以你必須改變你的想法的代碼。用於處理內部節點可以使用:

<?php 
//continuation of the code above 
$depth = $xml->depth; 
while ($xml->read() && $xml->depth >= $depth){ 
    //do something with the inner nodes 
} 
//the first time this Loop should fail is when the parser encountered 
//the </cat>-element, because the depth inside the cat-element is higher than 
//the depth of the cat-element itself 
//maybe you can search for other cat-nodes here, after you processed one 

我不能告訴你,如何重寫這段代碼的隨機存取的例子,但我希望,我能幫助你們。