PHP DOMDocument:解析未转义字符串时出错

2024-03-31

我在使用 PHP 解析 HTML 时遇到问题DOM文档.

我正在解析的 HMTL 有以下内容脚本标签:

<script type="text/javascript">
    var showShareBarUI_params_e81 =
    {
        buttonWithCountTemplate: '<div class="sBtnWrap"><a href="#" onclick="$onClick"><div class="sBtn">$text<img src="$iconImg" /></div><div class="sCountBox">$count</div></a></div>',
    }
</script>

这段代码有两个问题:

1) 里面的HTMLbuttonWithCountTemplatevar 没有转义。 DOMDocument 正确地管理它,在解析它时转义字符。不是问题。

2)接近尾声时,有一个带有未转义结束标签的 img 标签:

<img src="$iconImg" />

The />使 DOMDocument 认为脚本已完成,但是它缺少结束标签。如果您使用 getElementByTagName 提取脚本,您将在此 img 标记处关闭标记,其余部分将出现作为 HTML 上的文本.

我的目标是删除此页面中的所有脚本,因此如果我执行removeChild()在此标签上,该标签将被删除,但渲染页面时以下部分将显示为文本:

</div><div class="sCountBox">$count</div></a></div>',
        }
    </script>

修复 HTML 不是一个解决方案,因为我正在开发一个通用解析器并且需要处理所有类型的 HTML。

我的问题是,在将 HTML 提供给 DOMDocument 之前是否应该进行任何清理,或者是否有一个在 DOMDocument 上启用的选项以避免触发此问题,或者即使我可以在加载 HTML 之前删除所有标签。

有任何想法吗?


EDIT

经过一番研究,我发现了 DOMDocument 解析器的真正问题。考虑以下 HTML:

<div> <!-- Offending div without closing tag -->
<script type="text/javascript">
       var test = '</div>';
       // I should not appear on the result
</script>

使用以下 php 代码删除脚本标签(基于 Gholizadeh 的回答 https://stackoverflow.com/a/40762772/1371474):

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
libxml_use_internal_errors(true);
$dom->loadHTML(file_get_contents('js.html'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
//@$dom->loadHTMLFile('script.html'); //fix tags if not exist

while($nodes = $dom->getElementsByTagName("script")) {
    if($nodes->length == 0) break;
    $script = $nodes->item(0);
    $script->parentNode->removeChild($script);
}

//return $dom->saveHTML();
$final = $dom->saveHTML();
echo $final;

结果如下:

<div> <!-- Offending div without closing tag -->
<p>';
       // I should not appear on the result
</p></div>

问题是第一个 div 标签没有关闭,并且 DOMDocument 似乎将 JS 字符串内的 div 标签视为 html 而不是简单的 JS 字符串。

我可以做什么来解决这个问题?请记住,修改 HTML 不是一个选项,因为我正在开发一个通用解析器。


我在 html 文件上测试了以下代码,如下所示:

<p>some text 1</p>
<img src="http://www.example.com/images/some_image_1.jpg">
<p>some text 2</p>
<p>some text 3</p>
<img src="http://www.example.com/images/some_image_2.jpg">

<script type="text/javascript">
    var showShareBarUI_params_e81 =
    {
        buttonWithCountTemplate: '<div class="sBtnWrap"><a href="#" onclick="$onClick"><div class="sBtn">$text<img src="$iconImg" /></div><div class="sCountBox">$count</div></a></div>',
    }
</script>

<p>some text 4</p>
<p>some text 5</p>
<img src="http://www.example.com/images/some_image_3.jpg">

PHP代码是:

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

    $dom = new DOMDocument;
    $dom->preserveWhiteSpace = false;
    @$dom->loadHTML(file_get_contents('script.html'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
    //@$dom->loadHTMLFile('script.html'); //fix tags if not exist 

    $nodes = $dom->getElementsByTagName("script");

    foreach($nodes as $i => $node){
        $script = $nodes->item($i);
        $script->parentNode->removeChild($script);
    }

    //return $dom->saveHTML();
    $dom->saveHtmlFile('script.html');

它适用于给定的示例,我认为您应该使用我在加载 html 代码时使用的选项。

根据最后一个问题更新编辑:

实际上你不能用正则表达式解析[X]HTML(读这个link https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454了解更多信息) 但如果您的唯一目的是仅删除脚本标签,并且您可以确保没有</script>标签作为其之间的字符串。你可以使用这个正则表达式:

$html = mb_convert_encoding(file_get_contents('script2.html'), 'HTML-ENTITIES', 'UTF-8');
$new_html = preg_replace('/<script(.*?)>(.*?)<\/script>/si', '', $html);
file_put_contents('script-result.html', $new_html);

坦率地说,问题是您可能没有标准的 HTML 代码。但我认为最好尝试链接的其他库here https://stackoverflow.com/questions/3577641/how-do-you-parse-and-process-html-xml-in-php/3577662#3577662.

否则我想你应该编写一个特殊的解析器来删除脚本标签并处理其中的单引号和双引号。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PHP DOMDocument:解析未转义字符串时出错 的相关文章

  • 排除单个浏览器使用 CSS 类

    我想排除 Internet Explorer 使用特定的 CSS 类 这可能吗 Details 我有一个 css 类 看起来像 input type radio checked input type radio hover box shad
  • 正确的标头 php mysql blob 显示图像

    我正在尝试在我的 PHP 页面中显示来自 mysql blob 的图像 我知道这不是最佳实践 然后我会将其引入我的 iOS 应用程序中 我在设置页面标题时遇到问题 我认为需要将其设置为图像 所以 这显示了图像 但我不相信页眉是正确的 hea
  • 根据类别 woocommerce 更改同一产品的默认变体值

    我正在研究一种根据其所属类别显示同一产品的默认变体值的方法 例如 我出售一张带有蓝色和红色选项的卡 当用户进入 一 类别时 我希望默认值为蓝色 如果他属于第二类 则该值将为红色 我发现了一个钩子woocommerce product def
  • PHP 和 MySQL 的重音字符错误

    我的问题是 直接通过 PHP 编写的内容是正确重音的 但是当重音单词来自 MySQL 时 字母会像这样 我尝试使用html charset as ISO 8859 1它修复了 MySQL 字母 但破坏了其他字母 解决这一切的一种方法是设置我
  • 如何使用php在mysql数据库中添加照片? [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我对 PH
  • Laravel 类邮件程序不存在

    我将应用程序从 5 更新到 5 2 现在 当我调用 Mail send 时 它会返回一个异常 Class mailer 不存在 Mail send emails mail data gt content function m use to
  • 使用 IntlDateFormatter 转换非公历日期

    我应该如何使用将非公历日期转换为其他日历类型IntlDateFormatter 我要转换 1392 01 02 from persian to islamic日历 我尝试了以下代码 但它没有转换日历 formatter IntlDateFo
  • jQuery .val() 返回单选按钮的未定义

    我正在尝试获取 jQuery 中选中的单选按钮值 但它返回的值是 未定义 我搜索了这个问题的解决方案 但对我来说没有任何作用 我的 HTML 代码
  • phpstorm xdebug 与 symfony2 项目

    我正在尝试使用 xdebug 和 phpstorm 调试 symfony2 应用程序 我的本地开发环境是Ubuntu 14 04 with apache2 Xdebug版本是2 2 7 我在另一个 php 不是 symfony2 项目上使用
  • 使用模态表单 ajax 超出 HTMLFormElement.toString 的最大调用堆栈大小

    我想使用模态窗口中的 ajax 请求提交表单 单击此链接可打开该模式 a class btn btn primary i class fa fa edit i Write a review a 模态窗口 div class modal fa
  • html5 输入模式属性在表单之外不起作用?

    这把小提琴 http jsfiddle net 2gaw3 按预期工作 当用户输入无效的国家 地区代码时 它会显示警告 这另一个小提琴 http jsfiddle net y66vH 4 没有form元素 不起作用 看来输入的pattern
  • 如何在 WordPress HTML 中包含“onclick”对象

    我正在尝试将 onclick 对象添加到触发事件的单站点 即而不是多站点 WordPress 中的页面 代码是 a href Send a voice message a 当尝试保存代码时 WordPress 会删除 onclick 对象
  • 如何使用xquery查找节点并向其添加子节点?

    是否可以使用xpath xquery查询特定的xml节点 然后向其导入 添加子节点 示例 代码取自http codepad org gJ1Y2LjM http codepad org gJ1Y2LjM 这是在类似的问题中提出的 但不相同 1
  • Heredoc:常用的“EOT”实际上是什么意思?

    PHP s 定界例子 http www php net manual en language types string php language types string syntax heredoc似乎总是使用 EOT 有时是 EOD 作
  • 使水平滚动条始终可见,即使底部不在视图中

    我将用一个片段来开始这个问题 该片段几乎显示了我想要完成的任务 wrapper overflow hidden display flex sidebar min width 200px background 333 color FFF co
  • 使用 html5 分块上传文件

    我正在尝试使用 html5 的文件 API 分块上传文件 然后在服务器端用 php 重新组装它 我正在上传视频 但是当我在服务器端合并文件时 大小增加了 并且它变成了无效文件 请注意 以下 html5 代码仅适用于 chrome 浏览器 在
  • PHP 中的简单 JSON 请求

    我有以下 json country code latitude 45 9390 longitude 24 9811 zoom 6 address city country Romania country code RO region 我只想
  • 电话号码上未拾取结构化数据

    我在网站上有以下代码片段 当我通过 Google 结构化数据测试工具运行此程序时 它不会获取电话号码 我不确定我哪里错了 div class telephone number p Call Us a href 07749 918 143 a
  • SimpleXML插入处理指令(样式表)

    我想集成一个XSL文件在一个XML给我的字符串php CURL命令 我试过这个 output XML gived me by curl option hotel simplexml load string output hotel gt a
  • MYSQL 按喜欢/不喜欢和受欢迎程度排序

    我有评论表 其中包括喜欢和不喜欢的内容 现在我在正确的顺序上遇到了问题 实际上 我的系统在顶部显示了最多点赞的评论 我正在 youtube 上寻找类似系统的东西 这意味着 100like 100dislikes 的评论的顺序高于 1 1 我

随机推荐