illegal self closing node notation for empty nodes - outputting XHTML with PHP DOMDocument
我正在使用PHP中的XPATH处理XHTML的XML兼容输入,如下所示:
1 2 3 4 | $xml=new DOMDocument(); $xml->loadXML(utf8_encode($temp)); [...] $temp=utf8_decode($xml->saveXML()); |
出现的问题是,根据HTML5规范,节点可能不会自动关闭,例如
1 | <textarea id="something"></textarea> |
或div以供JS
使用
1 |
重新显示为
1 | <textarea id="something" /> |
和
1 |
我目前使用
同时XPATH坚持推出
1 | xmlns:default="http://www.w3.org/1999/xhtml |
以及在新创建的各个节点上,它会放置
1 2 3 4 | $temp=str_replace(' xmlns:default="http://www.w3.org/1999/xhtml" ',"",$temp); $temp=str_replace(' xmlns:default="http://www.w3.org/1999/xhtml"',"",$temp); $temp=str_replace('<default:',"<",$temp); $temp=str_replace('</default:',"</",$temp); |
?
编辑:我真的在愚蠢的搜索和替换上遇到了麻烦,并且我不打算用RegExp攻击输出XHTML。考虑以下示例:
1 |
显然,自关闭div是非法的(至少在一种情况下,我无法将其作为mime application / xhtml xml输出,但被迫使用mime text / html),并且在所有其他情况下,它们肯定不会验证。 很抱歉收到的答复很晚,但是您知道...是圣诞节。 :D 在您的示例中
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
{
$voids = ['area',
'base',
'br',
'col',
'colgroup',
'command',
'embed',
'hr',
'img',
'input',
'keygen',
'link',
'meta',
'param',
'source',
'track',
'wbr'];
// Every empty node. There is no reason to match nodes with content inside.
$query = '//*[not(node())]';
$nodes = (new DOMXPath($dom))->query($query);
foreach ($nodes as $n) {
if (! in_array($n->nodeName, $voids)) {
// If it is not a void/empty tag,
// we need to leave the tag open.
$n->appendChild(new DOMComment('NOT_VOID'));
}
}
// Let's remove the placeholder.
return str_replace('<!--NOT_VOID-->', '', $dom->saveXML());
}
2
3
4
5
6
7
8
$dom->loadXML(<<<XML
<html>
<textarea id="something"></textarea>
</html>
XML
);
2
3
4
5
<html>
<textarea id="something"></textarea>
</html>
圣诞快乐! ^ _ ^
您是否不知道可以编写HTML5并将其用作XML,请看以下内容:"对于许多人来说似乎不太清楚。因此,让我们保持记录吧。HTML5可以用html和XML编写。
接下来要实际将任何PHP示例用作XML,请设置相应的标头:
1 |
在实际的XML文档中,如果没有不使用斜杠,就不能编写任何自闭标签。没有
我们发现在
中使用LIBXML_NOEMPTYTAG选项
1 2 3 4 | $xml=new DOMDocument(); $xml->loadXML(utf8_encode($temp)); // do stuff with the DOM $temp=utf8_decode($xml->saveXML(NULL, LIBXML_NOEMPTYTAG)); |
不能"解决"问题,但可以解决该问题。 HTML5规范命名了多个" void elements "。它们是:
由于缺少定义的内容,因此可以通过简单的RegExp(缺少实际解决方案)使用void元素来实现此目的:
1 | $temp = preg_replace('#></(area|base|br|col|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)>#si', '/>', $temp); |
之后,我们可以继续进行我在问题中遇到的其他愚蠢修补程序:
1 2 3 | $temp=str_replace(' xmlns:default="http://www.w3.org/1999/xhtml"','',$temp); $temp=str_replace('<default:',"<",$temp); $temp=str_replace('</default:',"</",$temp); |