使用 PHP DOMDocument 时 <gcse:search> 转换为 <search>
<gcse:search> converted to <search> when using PHP DOMDocument
我有以下 HTML 代码和自定义标签 <gcse:search>
。它来自“自定义 Google 搜索引擎”以嵌入页面。
然而,在通过 PHP DOMDocument 解析后,<gcse:search>
被转换为 <search
> 破坏了功能。
<?php
$html = <<<EOD
<!DOCTYPE html>
<html>
<body>
<gcse:search enablehistory="false"></gcse:search>
</body>
</html>
EOD;
libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->loadHTML($html);
echo $dom->saveHTML();
输出:
<!DOCTYPE html>
<html>
<body>
<search enablehistory="false"></search>
</body>
</html>
您可以在解析 html 并在 saveHtml()
调用之后将它们转换回之前用占位符替换命名空间。
<?php
$html = <<<EOD
<!DOCTYPE html>
<html>
<body>
<gcse:search enablehistory="false"></gcse:search>
<gcse:test enablehistory="false"></gcse:test>
<mynamespace:testing enablehistory="false">test</mynamespace:testing>
</body>
</html>
EOD;
$htmlNamespaces = ['gcse:', 'mynamespace:'];
$namespaceReplacements = array_map(function($index){
return "ns__" . $index;
}, array_keys($htmlNamespaces));
$html = str_replace($htmlNamespaces, $namespaceReplacements, $html);
libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->loadHTML($html);
$rawHtml = $dom->saveHTML();
$formattedHtml = str_replace($namespaceReplacements, $htmlNamespaces, $rawHtml);
echo $formattedHtml;
结果:
<!DOCTYPE html>
<html>
<body>
<gcse:search enablehistory="false"></gcse:search>
<gcse:test enablehistory="false"></gcse:test>
<mynamespace:testing enablehistory="false">test</mynamespace:testing>
</body>
</html>
我找到的唯一解决方案是将 :
替换为 ___
,然后在 saveHTML()
之后替换回来。
$html = preg_replace('/<(\/?)([a-z]+)\:/', '<___', $html);
$doc->loadHTML($html);
// do stuff
$html = preg_replace('/<(\/?)([a-z]+)___/', '<:', $doc->saveHtml());
我有以下 HTML 代码和自定义标签 <gcse:search>
。它来自“自定义 Google 搜索引擎”以嵌入页面。
然而,在通过 PHP DOMDocument 解析后,<gcse:search>
被转换为 <search
> 破坏了功能。
<?php
$html = <<<EOD
<!DOCTYPE html>
<html>
<body>
<gcse:search enablehistory="false"></gcse:search>
</body>
</html>
EOD;
libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->loadHTML($html);
echo $dom->saveHTML();
输出:
<!DOCTYPE html>
<html>
<body>
<search enablehistory="false"></search>
</body>
</html>
您可以在解析 html 并在 saveHtml()
调用之后将它们转换回之前用占位符替换命名空间。
<?php
$html = <<<EOD
<!DOCTYPE html>
<html>
<body>
<gcse:search enablehistory="false"></gcse:search>
<gcse:test enablehistory="false"></gcse:test>
<mynamespace:testing enablehistory="false">test</mynamespace:testing>
</body>
</html>
EOD;
$htmlNamespaces = ['gcse:', 'mynamespace:'];
$namespaceReplacements = array_map(function($index){
return "ns__" . $index;
}, array_keys($htmlNamespaces));
$html = str_replace($htmlNamespaces, $namespaceReplacements, $html);
libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->loadHTML($html);
$rawHtml = $dom->saveHTML();
$formattedHtml = str_replace($namespaceReplacements, $htmlNamespaces, $rawHtml);
echo $formattedHtml;
结果:
<!DOCTYPE html>
<html>
<body>
<gcse:search enablehistory="false"></gcse:search>
<gcse:test enablehistory="false"></gcse:test>
<mynamespace:testing enablehistory="false">test</mynamespace:testing>
</body>
</html>
我找到的唯一解决方案是将 :
替换为 ___
,然后在 saveHTML()
之后替换回来。
$html = preg_replace('/<(\/?)([a-z]+)\:/', '<___', $html);
$doc->loadHTML($html);
// do stuff
$html = preg_replace('/<(\/?)([a-z]+)___/', '<:', $doc->saveHtml());