【问题标题】:XPath query off a XPath result and get childNodes HTMLXPath 查询 XPath 结果并获取 childNodes HTML
【发布时间】:2016-05-21 11:02:03
【问题描述】:

我正在尝试弄清楚如何从 jquery 结果中获取 HTML,同时能够从 PHP 中的结果中获取 jquery。

这是我目前使用的代码

 $url = 'http://www.foobar.com';
$output = file_get_contents($url);
$doc = new DOMDocument();

libxml_use_internal_errors(true); //Supress Warnings for HTML5 conversion issue
$doc->loadHTML($output);
libxml_use_internal_errors(false); //Start Showing Errors

$xpath = new DOMXpath($doc);


$CategoryString = '//tr[@class="playerSet"]';


$obj = new stdClass();

$x = 0;

foreach ($xpath->query($CategoryString) as $e) {

    $x++;
    $y = 0;
    foreach ($e->childNodes as $child) 
    { 

       $y++;
       if ($y == 1) $obj->players[$x]['name'] = $child->textContent;
       if ($y == 3) $obj->players[$x]['position'] = $child->textContent;
       if ($y == 5) $obj->players[$x]['team'] = $child->textContent;
       if ($y == 7) $obj->players[$x]['opp'] = $child->textContent;
    }
}


echo json_encode($obj);

现在这允许我在初始查询中循环遍历 childNodes。但是我想让这个更“精致”,而不是仅仅做一个廉价的循环。

我将如何执行另一个 xpath->查询 $e 以便我可以在 foreach 循环中循环?

例如,我想做 ('//td') 的查询,这样我就可以对初始查询结果 ($e) 的 //td 的结果进行 foreach

最后而不是显示 $child->textContent 我将如何获得 $child html?我尝试过在线搜索,但找不到快速参考来了解我可以使用什么来查看可能的结果。有没有办法我可以做一个回显来查看我可以使用 $child-> 而不是 textContent 的所有可能变量?我尝试了 nodeValue 但我没有得到我正在寻找的结果

编辑 - 找到了一种通过函数获取 DOM 的 innerHTML 的方法,以防万一有人好奇

function DOMinnerHTML(DOMNode $element) 
{ 
    $innerHTML = ""; 
    $children  = $element->childNodes;

    foreach ($children as $child) 
    { 
        $innerHTML .= $element->ownerDocument->saveHTML($child);
    }
    return $innerHTML; 
}

仍在寻找有关使用示例 jquery 从 $e 执行 foreach 的任何帮助。

编辑 - 澄清我需要从 $e 进行查询的原因

一个主要原因是因为在“名称”列中有时会重复,所以我只想通过这样做来获取名称...

'//td/span'

关闭主查询。如果不对主查询的结果执行另一个 jquery,我就无法做到这一点

除了“名称”之外,可能还有更多列,然后输出将作为 JSON_ENCODE 完成。我更新了我的示例代码以显示更多内容。

【问题讨论】:

  • $child html?你的意思是'innerHTML'等价物?没有直接在 php dom 中这样的东西,但是有很多关于如何模拟它的例子。并且每个 xpath 查询调用都可以被赋予一个“上下文”来操作,它只是一个节点/节点列表,新查询应该被限制在。
  • 是的,innerHTML 是我一直在寻找的,如果那不可能,那么至少知道如何从 $e 中进行适当的查询将使我更接近能够以我需要的方式使用数据到。

标签: php


【解决方案1】:

我会回答你提出的两个问题:

1。我将如何从 $e 中执行另一个 xpath->查询?

在原始的 xpath 查询中这样做会更有效,如下所示:

//tr[@class="playerSet"]/td

这将为具有 playerSet 类的 tr 父级的每个 td 提供结果。

但是,如果您愿意,您确实可以使用某个节点作为范围进行另一个查询。 DOMXPath query method 允许您将该节点作为第二个参数传递:

foreach ($xpath->query('//tr') as $e) {
    foreach ($xpath->query('td', $e) as $child) {
        echo $child->textContent;
    } 
} 

但在这种情况下,使用 XPath 查询来获取 TR 元素的 TD 子元素有点矫枉过正。使用childNodes 属性也可以正常工作(因为表行不应该有除TD 元素之外的任何其他子元素),并且效率更高:

foreach ($xpath->query('//tr') as $e) {
    foreach ($e->childNodes as $child) {
        echo $child->textContent;
    } 
} 

2。我如何获得 $child html?

使用saveHTML 方法:

$obj->players[$x]['innerHTML'] = $doc->saveHTML($e);

您可能还感兴趣:

XPath Location Paths 上的文档:

child::*选择上下文节点的所有子元素

child::text() 选择上下文节点的所有文本节点子节点

child::node() 选择上下文节点的所有子节点,无论其节点类型如何

例如,你可以玩这个:

//tr[@class="playerSet"]/child::node()

或者如果你想遍历整个标签树(不仅是下一级):

//tr[@class="playerSet"]/descendant::node()

【讨论】:

  • 我知道我可以只执行 /td,但我需要能够将所有内容分开,因为它们是单独的行,而且我很难跟踪新的“行”除非我先得到所有行,然后从行的每个 TD 中取出每个项目。最好能够像上面提到的那样在 $e 之外进行 xpath 查询,而不是在原始文件中尝试在 /td 中进行。我该怎么做呢?
  • 同样如上文在原文中所述,有时名称或另一列会有一个特定的$e 的结果,因此我可以指定我想要实际查看的 $e 子项内部的哪些信息。
  • 我在第一部分添加了一个关于嵌套 XPath 查询的示例。
猜你喜欢
  • 1970-01-01
  • 2012-01-02
  • 2013-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-04
  • 2010-12-22
  • 1970-01-01
相关资源
最近更新 更多