【问题标题】:PHP with DOM Xpath - Remove childNode and arrange string带有 DOM Xpath 的 PHP - 删除 childNode 并排列字符串
【发布时间】:2016-02-01 15:26:13
【问题描述】:

我有这个 html 结构:

<html>
  <body>
    <section>
      <div>
        <div>
          <section>
            <div>
              <table>
                <tbody>
                  <tr></tr>
                  <tr>
                    <td></td>
                    <td></td>
                    <td>
                      <i></i>
                      <div class="first-div class-one">
                        <div class="second-div"> soft </div>
                        130 cm / 15cm
                      </div>
                    </td>
                  </tr>
                  <tr></tr>
                </tbody>
              </table>
            </div>
          </section>
        </div>
      </div>
    </section>
  </body>
</html>

现在,我有了这个 XPath 代码:

$doc = new DOMDocument();
@$doc->loadHtmlFile('http://www.whatever.com');
$doc->preserveWhiteSpace = false;

$xpath = new DOMXPath( $doc );

$nodelist = $xpath->query( '/html/body/section/div[2]/section/div/table/tbody/tr[2]/td[3]/div' );
foreach ( $nodelist as $node ) {
    $result = $node->nodeValue."\n";
}

结果,我得到了“柔软的 130 厘米/15 厘米”。

但我想知道如何只得到“15”,所以我需要:

1.要知道如何摆脱childNode->nodeValue

2。一旦我有了“130 cm / 15cm”,就知道如何只获取“15”作为 PHP 中变量的 nodeValue。

你们能帮忙吗? 提前致谢

【问题讨论】:

  • nodeValue 只是一个文本字符串。一旦你有了那个字符串,DOM 的工作就完成了——你需要使用标准的 PHP 字符串操作(例如 substr)来操作它,然后将修改后的字符串塞回 DOM。
  • 是的,这就是为什么标题说'php with dom xpath'。如果我只想得到“130”,我知道该怎么做,但如果我只想要“15”,我就不知道了。此外,我需要的第一件事是要删除子 div 的值 'soft',这是一个 dom xpath 的东西。此外,围绕“15”的子字符串可能会在我正在使用的真实 html 代码中发生变化。
  • 我告诉你你有你的130 cm /15cm 字符串,现在必须使用标准的php字符串操作来进一步分解它。这意味着从技术上讲,您的问题与 dom 无关。 dom 完成了它的工作,现在你需要其他工具。
  • 我还没有'130 cm /15cm'。我有“柔软的 130 厘米/15 厘米”。请阅读原始问题。
  • @MarcB,我想你还没有读到有一个值为“软”的子 div。这是我问题的第一部分。

标签: php domxpath


【解决方案1】:

标签中的文本也是一个节点(一个子节点),尤其是DOMText。 通过查看该div 的子代,您可以找到DOMText 并得到它的nodeValue。下面是一个例子:

$doc = new DOMDocument();
$doc->loadHTML("<html><body><p>bah</p>Test</body></html>");
echo $doc->saveHTML();

$xpath = new DOMXPath( $doc );
$nodelist = $xpath->query( '/html/body' );
foreach ( $nodelist as $node ) {
    if ($node->childNodes)
            foreach ($node->childNodes as $child) {
                    if($child instanceof DOMText)
                            echo $child->nodeValue."\n"; // should output "Test".
            }
}

你的第二点可以用正则表达式轻松完成:

$string = "130 cm / 15cm";

$matches = array();
preg_match('|/ ([0-9]+) ?cm$|', $string, $matches);

echo $matches[1];

完整解决方案:

<?php

$strhtml = '
<html>
  <body>
    <section>
      <div>
        <div>
          <section>
            <div>
              <table>
                <tbody>
                  <tr></tr>
                  <tr>
                    <td></td>
                    <td></td>
                    <td>
                      <i></i>
                      <div class="first-div class-one">
                        <div class="second-div"> soft </div>
                        130 cm / 15cm
                      </div>
                    </td>
                  </tr>
                  <tr></tr>
                </tbody>
              </table>
            </div>
          </section>
        </div>
      </div>
    </section>
  </body>
</html>';

$doc = new DOMDocument();
@$doc->loadHTML($strhtml);
echo $doc->saveHTML();

$xpath = new DOMXPath( $doc );
$nodelist = $xpath->query( '/html/body/section/div/div/section/div/table/tbody/tr[2]/td[3]/div' );
foreach ( $nodelist as $node ) {
    if ($node->childNodes)
        foreach ($node->childNodes as $child) {
            if($child instanceof DOMText && trim($child->nodeValue) != "")
            {
                echo 'Raw: '.trim($child->nodeValue)."\n";
                $matches = array();
                preg_match('|/ ([0-9]+) ?cm$|', trim($child->nodeValue), $matches);
                echo 'Value: '.$matches[1]."\n";
            }
       }
}

【讨论】:

  • Weboide,感谢您的帮助。您的基本示例按预期工作正常。但这是我使用您的代码得到的输出:eval.in/511219 'Null' 结果来自我最后添加的 var_dump。如果我删除 var_dump,它不会输出任何内容。
  • 您的 xpath 与第一个 div[2] 错误,请参阅我的编辑,我添加了完整的解决方案。如果这解决了您的问题,请不要忘记投票并选择我的答案,谢谢!
猜你喜欢
  • 1970-01-01
  • 2014-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多