我有一个外部HTML源代码,我想要将其转换为本地XML文件或添加到MySQL数据库。
外部源主要是规范化的,并且(有些)是语义的,因此我需要做的就是使用XPATH
来获取所有td
内容或所有li
内容等。问题是这些项目偶尔使用<strong>
或<b>
或<i>
标记来设置我需要的元素的样式。
这在技术上是语义的,因为关键是要强调特定文本,开发人员可能希望使用不是浏览器默认值的CSS。
问题是我尝试抓取的实际内容被视为此内联元素的子项,因此像simplexml
或DOMDocument
和DOMNode
这样的PHP扩展会将它们视为此类内容。例如:
<table>
<tr><td>Thing 1</td><td>Thing 2</td></tr>
<tr><td>Thing 3</td><td>Thing 4</td></tr>
<tr><td><strong>Thing 5</strong></td><td><strong>Thing 6</strong></td></tr>
</table>
将导致:
[table] =>
[tr] =>
[td] => Thing 1
[td] => Thing 2
[tr] =>
[td] => Thing 3
[td] => Thing 4
[tr] =>
[td] =>
[strong] => Thing 5
[td] =>
[strong] => Thing 6
显然上面并不是simplexml返回的内容,但上面反映了一般问题。
有没有办法,使用已经内置到DOMDocument中的参数或使用额外复杂的XPath查询来获取td
元素的内容,其中任何子元素(如果有的话)都被剥夺了它们的后代状态并将所有内容视为查询元素的文本?
目前,我所拥有的唯一解决方案是:
a)有一个foreach
循环检查每个结果,如:
$result_text = ($result -> strong) ? $result - strong : $result;
b)使用正则表达式从HTML字符串中删除任何<strong>
标记,然后将其导入任何预构建的类,如simplexml或DOMDocument。
答案 0 :(得分:1)
在使用正则表达式解析html之前,请先阅读this的第一个答案,如果只是为了娱乐。 XPath就是答案,获取td的文本而不是继续解析它。因此,您只需搜索//td
之类的内容并完整地获取结果(而不是继续构建树,以便您拥有强大的树叶或其他任何东西。
答案 1 :(得分:1)
您不能只使用strip_tags()删除额外标记吗?
$table = simplexml_load_string(
'<table>
<tr><td>Thing 1</td><td>Thing 2</td></tr>
<tr><td>Thing 3</td><td>Thing 4</td></tr>
<tr><td><strong>Thing 5</strong></td><td><strong>Thing 6</strong></td></tr>
</table>'
);
foreach ($table->xpath('//td') as $td)
{
$content = strip_tags($td->asXML());
echo $content, "\n";
}
答案 2 :(得分:0)
如果你正在使用DOMDocument,那么一旦你选择了一个DOMNode,属性textContent
应该只包含它的文本部分而且它只是所有的孩子...... 完全你是什么的要求。
$table = '<table>
<tr><td>Thing 1</td><td>Thing 2</td></tr>
<tr><td>Thing 3</td><td>Thing 4</td></tr>
<tr><td><strong>Thing 5</strong></td><td><strong>Thing 6</strong></td></tr>
</table>';
$dom = new DOMDocument;
$dom->loadHTML($table);
$xpath = new DOMXPath($dom);
$els = $xpath->query('//td');
echo $els->item(4)->textContent; //Thing 5
或者,根据节点的类型,您也可以检查nodeValue
。我不记得确切的区别,但textContent就是你想要的。