我最近收到了解析HTML文档中所有文本节点的帮助。结果代码如下:
$doc = new DOMDocument();
$doc->loadHTML($contents);
$doc->loadHTML("<p>not in the brackets..</p>");
$xpath = new DOMXPath($doc);
$textnodes = $xpath->evaluate('//text()');
使用以下摘录:
<p>This is a <b>nested <i>HTML</i> tag<b>...</p>
我能够创建一个元素数组:
Array
(
[0] => This is a
[1] => nested
[2] => HTML
[3] => tag
[4] => ...
)
但我真正想要做的是检索所有文本节点,但允许某些HTML标记“查看”。例如,我不希望将<i>
,<b>
和<u>
标记解析为单个节点;我宁愿他们加入到上一个文本节点。理想情况下,上面的数组看起来像这样:
Array
(
[0] => This is a nested HTML tag...
)
另一方面,<p>
标记应该被识别为单独的节点。所以下面的文字:
<p>paragraph 1 <b>here</b></p> <p>paragraph 2</b>
理想情况下会被解析为:
Array
(
[0] => paragraph 1 <b>here</b>
[1] => paragraph 2
我已经完成了一些关于XPath和PHP DOM的阅读,但老实说,我真的不知道如何解决这个问题。任何人都能指出我正确的方向吗?谢谢。
修改
只是为了澄清输出必须是数组格式;我的目的是解析页面中的所有文本,以便可以在翻译文件中使用它。因此,在解析的文本中需要某些HTML标记(<b>
等),以便在新的翻译文件中将完整的句子保持在一起 - 并保持标记大致完整。
答案 0 :(得分:0)
考虑在“查看标签”上使用strip_tags,并在要实际拆分的标签上使用允许标签的第二个参数。
答案 1 :(得分:0)
如果您有一个节点并希望将其标准化为纯文本:
XPATH: 'string(thenode)'
DOM: $thenode->textContent;
这将忽略所有不是文本节点的子节点,并将其作为单个字符串返回。
因此,在您的示例中,像string(//p)
这样的xpath将为您提供一个包含所有元素的纯文本段落数组。您可以使用getElementsByTagName()
对DOM执行相同的操作,并为每个结果获取textContent
属性。
如果您的要求比这更复杂,那么最好使用带有身份转换的XSL来生成更符合您自己喜欢的新DOM树。例如,如果您有一些您想要的顶级节点(如<p>
),并且想要删除一些但不是所有子节点(例如,“保持em
和strong
,但是向上折叠cite
,那么DOM解决方案将非常繁琐。