2017-07-06 101 views
0

我有一個xpath的問題。我想從這個獲取數據:PHP Xpath試圖獲取非對象的屬性

<div class="clan__table"> 
     <div class="clan__headers"> 
     <div class="clan__headerCaption">Rank</div> 
     <div class="clan__headerCaption">Name</div> 
     <div class="clan__headerCaption">Level</div> 
     <div class="clan__headerCaption">League</div> 
     <div class="clan__headerCaption">Trophies</div> 
     <div class="clan__headerCaption">Donations</div> 
     <div class="clan__headerCaption">Role</div> 
     </div>  
     <div class="clan__rowContainer"> 
     <div class="clan__row"> 
          #2 
        </div> 
     <div class="clan__row"> 
      <a class="ui__blueLink" href='/profile/8C2PQYYL'>Voodoo</a> 
     </div> 
     <div class="clan__row"> 
      <span class="clan__playerLevel">11</span> 
     </div> 
     <div class="clan__row"> 
      <div class="clan__leagueContainer"> 
          <div class="league__1"></div> 
         </div> 
     </div> 
     <div class="clan__row"> 
      <div class="clan__cup">4000</div> 
     </div> 
     <div class="clan__row">96</div> 
     <div class="clan__row"> 
      Co-Leader 
        </div> 
     </div> 
.... 
.... 

這是我的代碼:

$xpath2 = new DOMXPath($doc2); 
$text = ""; 
$playerlist_ul = $xpath2->query("//div[@class='clan__table']")->item(0); 
$playernodes = $playerlist_ul->childNodes; 
if (!empty($playernodes)) 
{ 
    foreach ($playernodes as $node2) 
    { 
     if ($node2->hasChildNodes()) 
     { 

      $playerinfo = new DOMDocument(); 
      libxml_use_internal_errors(true); 
      $playerinfo->loadHTML($node2->ownerDocument->saveHTML($node2)); 
      $xpath3 = new DOMXPath($playerinfo); 


      $player['level'] = $xpath3->query("//span[@class='clan__playerLevel']")->item(0)-> 
       textContent; 
      $player['name'] = $xpath3->query("//a[@class='ui__blueLink']")->item(0)-> 
       textContent; 
      $player['id'] = $xpath3->query("//a[@class='ui__blueLink']/@href")->item(0)-> 
       textContent; 
      $player['trophy'] = $xpath3->query("//div[@class='clan__cup']")->item(0)-> 
       textContent; 
      $player['role'] = $xpath3->query("//div[@class='clan__row']")->item(6)-> 
       textContent; 
      $player['donate'] = $xpath3->query("//div[@class='clan__row']")->item(5)-> 
       textContent; 
      $player['clan_position'] = $xpath3->query("//div[@class='clan__row']")->item(0)-> 
       textContent; 


      $players[] = $player; 
     } 
    } 
} 

幾乎一切工作,但我得到的錯誤:試圖讓非對象的屬性與$每行播放器[「...」] 這是導致

array (size=49) 
    0 => 
    array (size=6) 
     'level' => null 
     'name' => null 
     'trophy' => null 
     'role' => null 
     'donate' => null 
     'clan_position' => null 
    1 => 
    array (size=6) 
     'level' => string '11' (length=2) 
     'name' => string '/profile/8C2PQYYL' (length=17) 
     'trophy' => string '4056' (length=4) 
     'role' => string ' 
      Co-Leader 
        ' (length=44) 
     'donate' => string '192' (length=3) 
     'clan_position' => string ' 
          #1 
        ' (length=52) 

也有一些是錯誤的數組[0] 所以我的問題是:如何避免這種錯誤?

回答

1

DOMXpath::query()將始終返回DOMNodeList實例。您正在從該列表中獲取節點並訪問其屬性$textContent。如果這裏沒有節點,就會發生錯誤。

如果您使用DOMXpath::evaluate(),很容易解決。 Xpath表達式允許類型轉換,但只有DOMXpath::evaluate()支持標量返回值。

因此,基本上你使用foreach()表達式返回一個節點列表,並在該表達式中使用類型轉換來表示細節。這裏不需要保存片段並將其作爲單獨的文檔加載,您可以爲表達式提供上下文節點。

$document = new DOMDocument(); 
$document->loadHtml($html); 
$xpath = new DOMXpath($document); 

$expression = "//div[@class='clan__table']/div[@class='clan__rowContainer']"; 
foreach ($xpath->evaluate($expression) as $clanNode) { 
    $result = [ 
    'level' => $xpath->evaluate("string(.//span[@class='clan__playerLevel'])", $clanNode), 
    'name' => $xpath->evaluate("string(.//a[@class='ui__blueLink'])", $clanNode), 
    'id' => $xpath->evaluate("string(.//a[@class='ui__blueLink']/@href)", $clanNode), 
    'trophy' => $xpath->evaluate("string(.//div[@class='clan__cup'])", $clanNode), 
    'role' => $xpath->evaluate("string(.//div[@class='clan__row'][7])", $clanNode), 
    'donate' => $xpath->evaluate("string(.//div[@class='clan__row'][6])", $clanNode), 
    'clan_position' => $xpath->evaluate(
     "normalize-space(.//div[@class='clan__row'][1])", $clanNode 
    ) 
    ]; 
    var_dump($result); 
} 

輸出:

array(7) { 
    ["level"]=> 
    string(2) "11" 
    ["name"]=> 
    string(6) "Voodoo" 
    ["id"]=> 
    string(17) "/profile/8C2PQYYL" 
    ["trophy"]=> 
    string(4) "4000" 
    ["role"]=> 
    string(46) " 
      Co-Leader 
        " 
    ["donate"]=> 
    string(2) "96" 
    ["clan_position"]=> 
    string(2) "#2" 
} 

一點有關XPath string()是顯式類型轉換。它返回列表的第一個節點的文本內容或一個空字符串。 normalize-space()包含一個隱式類型轉換,但是它會刪除該字符串,並用單個空格替換所有空白組。 [6]是節點列表中的第6個元素。

相關問題