我遇到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;
}
}
}
一切几乎正常但我得到错误:尝试使用$ player [&#39; ....&#39;]获取每行中非对象的属性 这是结果
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]有问题 所以我的问题是:如何避免这个错误?
答案 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个元素。