我正在使用解析器输出PHP DOM的特定元素,例如HTML页面中的标题标签,图像等(我无法控制页面),我想得到nodeValue / textContent没有连接的DOM节点,在可视HTML中没有保留有效的空格(读取:换行符)。
例如,导出标题标签的当前代码如下,简单明了:
SCHYEAR
这对于标准字符串非常有用,但是如果你有HTML,例如:
function getHeadingTags($content){
$this->dom = new DomDocument();
@$this->dom->loadHTML($contents);
$this->xpath = new DOMXPath($this->dom);
$this->xpath->registerNamespace("php", "http://php.net/xpath");
$this->xpath->registerPHPFunctions();
$nodes = $this->xpath->query('//h1|//h2|//h3|//h4|//h5|//h6');
$results = array();
if ($nodes->length > 0)
{
foreach ($nodes as $node)
{
$results[$node->tagName][] = trim($node->textContent);
}
}
return $results;
}
结果是令人讨厌的串联字符串:
<h1>This is a heading<br>that spans two lines</h1>
当然,人们可以预先放置This is a headingthat spans two lines
元素,但它只是感觉有点hacky。通过使用递归<br>
和foreach循环我已经处理了元素的层次结构我只是想知道是否有一个解决方案不需要我觉得非常hacky找到并替换其余的工作顶级DOM元素。
我认为这也是列表的问题,例如以下代码:
$node->childNodes
我假设<ul>
<li>Test</li>
<li>Test2</li>
</ul>
上的nodeValue输出类似于<ul>
而不是希望TestTest2
我知道这是预期的行为但是我希望有一个体面的工作,如果有人有一个可以交?
答案 0 :(得分:1)
您可以递归搜索DOMText节点的节点的子节点,并使用空格连接它们:
function getNodeText(DOMNode $node) {
if (is_a($node, "DOMText"))
return trim($node->nodeValue);
$nodeValues = array();
foreach ($node->childNodes as $child)
{
$nodeText = getNodeText($child);
if ($nodeText != "")
{
$nodeValues[] = $nodeText;
}
}
return trim(implode(" ", $nodeValues));
}
function getHeadingTags($content) {
$dom = new DomDocument();
$dom->loadHTML($content);
$xpath = new DOMXPath($dom);
$xpath->registerNamespace("php", "http://php.net/xpath");
$xpath->registerPHPFunctions();
$nodes = $xpath->query('//h1|//h2|//h3|//h4|//h5|//h6');
$results = array();
if ($nodes->length > 0)
{
foreach ($nodes as $node)
{
$results[$node->tagName][] = getNodeText($node);
}
}
return $results;
}
请在此处查看示例:https://3v4l.org/pYMFr
答案 1 :(得分:0)
您可能需要逻辑地(在您的脑海中)分离值和输出。
根据您遇到问题的时间,您可以使用“markdown”之类的内容来替换HTML-Tags,或者只是替换一些像您想要的换行符。我编写了一些解析器,并且经常将原始HTML保存在数据库字段中,因此我始终可以控制在分隔字段中保存的节点。
关于列表,您可以替换&lt; / li&gt;由&lt; / br&gt;。 如果你永远不知道你解析的页面,你可能会假设还包括许多其他标签,即dl,dt,dd,address,....
即使您按照标准验证所有HTML标签,也不能保证它们像这样使用。一个例子是使用ul-lists构建的菜单,在CSS样式化之后,页面上的显示通常会大不相同,因此可以更改元素的许多属性,并且不能依赖块元素的原始属性或内联 - 元件。
[1] https://en.wikipedia.org/wiki/Markdown [2] https://en.wikipedia.org/wiki/ReStructuredText