domdocument 相关问题

DOMDocument是指封装DOM(文档对象模型)的类。各种语言和技术对此PHP,COM,C ++,ActiveX使用名称DOMDocument

从下拉列表中选择要传递给变量的选项并使用新的 domDocument 重新加载页面

好的。已经为此奋斗了很长时间了。我有以下代码从添加站点获取 html: $articleClassName = '相对隔离 sf-search-ad 光标指针溢出隐藏相对转换...

回答 1 投票 0

如何防止 DOMDocument 转换为 unicode

我正在尝试获取 PHP 中 DOMElement 的内部 HTML。标记示例: ... 这里有一些 有趣  ... 我正在尝试在 PHP 中获取 DOMElement 的内部 HTML。标记示例: <div>...</div> <div id="target"><p>Here's some &nbsp; <em>funny</em> &nbsp; text</p></div> <div>...</div> <div>...</div> 将上面的字符串输入变量$html,我正在做: $doc = new DOMDocument(); @$doc->loadHTML("<html><body>$html</body></html>"); $node = $doc->getElementById('target') $markup = ''; foreach ($node->childNodes as $child) { $markup .= $child->ownerDocument->saveXML($child); } 生成的 $markup 字符串如下所示(转换为 JSON 以显示不可见字符): "<p>Here's some \u00a0 <em>funny<\/em> \u00a0 text<\/p>" 所有 &nbsp; 字符已转换为 Unicode 不间断空格,这破坏了我的应用程序。 在我的理想世界中,有一种方法可以检索目标 div as-is 中的原始 HTML 字符串,而无需 DomDocument 对其执行任何操作。这似乎不可能,所以下一个最好的办法是以某种方式关闭此字符转换。到目前为止我已经尝试过: 设置$doc->substituteEntities = false;没有结果。将其更改为 true 也没有帮助。 切换$doc->preserveWhiteSpace,任何方式都没有变化 将 saveXML 更改为 saveHTML。没有什么区别。 最后我求助于这个 hack,它有效,但感觉不是正确的解决方案。 $markup = str_replace("\xc2\xa0", '&nbsp;', $markup); 当然有更好的方法吗? 您可以使用正则表达式来查找所有非标准(即不可见的非 ASCII)字符。然后将非常神秘的函数mb_encode_numericentity()应用于这些字符,这样它就不会触及您的标记等: <?php $html = <<< HTML <div>...</div> <div id="target"><p>Here's some &nbsp; <em>funny</em> &nbsp; text</p></div> <div>...</div> <div>...</div> HTML; $doc = new DOMDocument(); libxml_use_internal_errors(); $doc->loadHTML("<html><body>$html</body></html>"); $node = $doc->getElementById('target'); $markup = ''; foreach ($node->childNodes as $child) { $markup .= $child->ownerDocument->saveHTML($child); } $markup = preg_replace_callback( "/[^ -~]/u", fn ($m) => mb_encode_numericentity($m[0], [0x00, 0xff, 0, 0xff], "UTF-8"), $markup ); echo $markup; 输出: <p>Here's some &nbsp; <em>funny</em> &nbsp; text</p> 我也遇到了这个问题,基本上已经描述在这里了。 提供的解决方案对我有用,但只有&nbsp;字符失败了,所以我来到这里。 miken32 提供的解决方案对我不起作用,至少在保存时不起作用,但在加载 html 时不起作用。解决办法是: $dom = new DOMDocument(); $dom->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8')); 链接的 stackoverflow 问题和帮助我解决问题的这篇博文中也描述了此解决方案。

回答 2 投票 0

为什么 DOMDocument::saveHTML() 的行为在将 UTF-8 编码为样式和脚本元素中的实体时有所不同?

给定一个使用包含表情符号字符的样式表构建的 DOMDocument,在将 DOM 序列化回 HTML 时,我发现了一些奇怪的行为。 $html = <<< HTML 考虑到使用包含表情符号字符的样式表构建的 DOMDocument,我在将 DOM 序列化回 HTML 时发现了一些奇怪的行为。 $html = <<< HTML <!DOCTYPE html> <html> <head> <meta charset=utf-8> <style>span::before{ content: \"⚡️\"; }</style> </head> <body> <span></span> </body> </html> HTML; $dom = new DOMDocument(); $dom->loadHTML($html); echo $dom->saveHTML($dom->documentElement); echo $dom->saveHTML(); $dom->saveHTML($dom->documentElement)的结果是(根据需要): <html><head><meta charset="utf-8"> <style>span::before{ content: "⚡️"; }</style> </head><body><span></span></body></html> 但是 $dom->saveHTML() 返回(错误地): <html><head><meta charset="utf-8"> <style>span::before{ content: "&#9889;&#65039;"; }</style> </head><body><span></span></body></html> 请注意表情符号“⚡️”如何编码为样式表内的 HTML 实体 &#9889;&#65039;。它被视为文字字符串,因为应使用 CSS 转义 \26A1。 我尝试设置$dom->substituteEntities = false但没有任何效果。 相同的 HTML 实体转换也发生在 <script> 元素内部,这会在浏览器中导致类似的问题。 通过在线 PHP shell 进行测试:https://3v4l.org/jMfDd 您应该在 DOMDocument 上加载带有表情符号的 HTML 之前转换编码: $dom->loadHTML(mb_convert_encoding($htmlCode, 'HTML-ENTITIES', 'UTF-8')); 编辑:正如帖子所有者提到的,mb_convert_enconding 在未来的 PHP 版本中已被弃用(目前在 8.2.5 上进行了测试并且工作正常)。对于更高版本的 PHP,请查看 https://php.watch/versions/8.2/mbstring-qprint-base64-uuencode-html-entities-deprecated#html

回答 1 投票 0

PHP Domdocument 换行符无法使用创建元素工作

我正在尝试使用 PHP dom 文档创建一个 div 元素,它按预期工作。但是当我尝试插入换行符时它不起作用。我已经将 dom 文档导入到 mpdf 中以供通用...

回答 1 投票 0

PHP 8.1 DOM文档序列化

我正在尝试使以下类与本机 PHP 序列化兼容,特别是在 PHP 8.1 上运行时。 SerializedDomDocument 类扩展 DOMDocument { 私有$xmlData;

回答 3 投票 0

PHP DOMDocument 用文本节点替换多个子节点

我有一个示例字符串,如下所示: $feed_status = '很高兴再次见到你们 我有一个示例字符串,如下所示: $feed_status = 'Nice to see you all back again <img src="http://example.com/file/pic/emoticon/default/smile.png" alt="Smile" title="Smile" title="v_middle" /> <img src="http://example.com/file/pic/emoticon/default/smile.png" alt="Smile" title="Smile" title="v_middle" /> <img src="http://example.com/file/pic/emoticon/default/smile.png" alt="Smile" title="Smile" title="v_middle" />'; 在这个示例中,我刚刚向字符串添加了三个 <img> 标签,但在实际情况下,该字符串可能包含零个或多个 <img> 标签。 我想获取每个 <img> 标签的 src 属性中存在的文件名,并创建这些文件名的数组。然后我必须用标题为 <img> 的数组中的字符串替换这些 $emoticon_codes 标签,该数组是根据 <img> 标签中存在的文件名动态创建的。字符串的替换应该以相同的顺序进行。 为此,我尝试了以下代码。直到创建名为 $emoticon_codes 的动态数组,一切正常,但我面临着用数组 <img> 中的字符串替换当前 $emoticon_codes 标签的代码。那么有人可以帮助我纠正我在代码中替换字符串中的 <img> 标签时所犯的错误吗? 以下是我的代码: $doc = new DOMDocument(); $doc->loadHTML($feed_status); $imageTags = $doc->getElementsByTagName('img'); if(count($imageTags)) { $emoticon_codes = array(); foreach($imageTags as $tag) { if (basename($tag->getAttribute('src')) == 'evilgrin.png') { array_push($emoticon_codes, '\ue404'); } if (basename($tag->getAttribute('src')) == 'grin.png') { array_push($emoticon_codes, '\ue415'); } if (basename($tag->getAttribute('src')) == 'happy.png') { array_push($emoticon_codes, '\ue057'); } if (basename($tag->getAttribute('src')) == 'smile.png') { array_push($emoticon_codes, '\ue056'); } if (basename($tag->getAttribute('src')) == 'surprised.png') { array_push($emoticon_codes, '\ue107'); } if (basename($tag->getAttribute('src')) == 'tongue.png') { array_push($emoticon_codes, '\ue105'); } if (basename($tag->getAttribute('src')) == 'unhappy.png') { array_push($emoticon_codes, '\ue403'); } if (basename($tag->getAttribute('src')) == 'waii.png') { array_push($emoticon_codes, '\ue407'); } if (basename($tag->getAttribute('src')) == 'wink.png') { array_push($emoticon_codes, '\ue405'); } } /*Till here everything works fine. The array $emoticon_codes is also getting generated finely*/ /*Following is the code giving problem to me,*/ $t = 0; foreach($imageTags as $img) { $img->parentNode->replaceChild($img, $doc->createTextNode($emoticon_codes[$t])); $t++; if ($t > count($emoticon_codes)) { break; } } } 我想要的输出字符串应该如下所示: 很高兴再次见到你们\ue056\ue056\ue056; 如果您尝试更改多个子项,则需要一些“回归”来进行一些更改,我建议尝试将每个替换映射到数组中,而不是使用多个 if 语句。示例: echo $feed_status; 示例输出 你有这个: $feed_status = "Nice to see you all back again <img src=\"http://52.1.47.143/file/pic/emoticon/default/smile.png\" alt=\"Smile\" title=\"Smile\" title=\"v_middle\" /><img src=\"http://52.1.47.143/file/pic/emoticon/default/smile.png\" alt=\"Smile\" title=\"Smile\" title=\"v_middle\" /><img src=\"http://52.1.47.143/file/pic/emoticon/default/smile.png\" alt=\"Smile\" title=\"Smile\" title=\"v_middle\" />"; $doc = new DOMDocument(); @$doc->loadHTML($feed_status, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); $imageTags = $doc->getElementsByTagName('img'); $replacements = array( 'evilgrin.png' => '\ue404', 'grin.png' => '\ue415', 'happy.png' => '\ue057', 'smile.png' => '\ue056', 'surprised.png' => '\ue107', 'tongue.png' => '\ue105', 'unhappy.png' => '\ue403', 'waii.png' => '\ue407', 'wink.png' => '\ue405', ); // regression $i = $imageTags->length - 1; while($i > -1) { $tag = $imageTags->item($i); $basename = basename($tag->getAttribute('src')); if(isset($replacements[$basename])) { // if the file name matches // make replacements $r = $replacements[$basename]; $text = $doc->createTextNode($r); $tag->parentNode->replaceChild($text, $tag); } $i--; } // append to string container again $feed_status = ''; foreach($doc->childNodes->item(0)->childNodes as $e) { $feed_status .= $doc->saveHTML($e); } echo $feed_status; 但是,这只循环通过 foreach($imageTags as $img) { $img->parentNode->replaceChild($img, $doc->createTextNode($emoticon_codes[$t])); $t++; if ($t > count($emoticon_codes)) { break; } } ,而不是 $imageTags。 你需要这个: $emoticon_codes

回答 2 投票 0

将 2 列 HTML 表格内容转换为 2d 数组

我正在尝试使用 PHP 将 HTML 表的单元格值解析为具有预定键的关联数组的索引数组。 $htmlContent = ' 测试1<... 我正在尝试使用 PHP 将 HTML 表的单元格值解析为具有预定键的关联数组的索引数组。 $htmlContent = '<table> <tr> <th>test1</th> <td>test1-1</td> </tr> <tr> <th>test2</th> <td>test2-2</td> </tr> </table>'; 我想要这个结果: [ ['name' => "test1", 'value' => "test1-1"], ['name' => "test2", 'value' => "test2-2"], ] 我目前的结果只是: [ ['test1' => 'test1-1', 'test2' => 'test2-2'] ]; 这是我的编码尝试: $DOM = new DOMDocument(); $DOM->loadHTML($htmlContent); $Header = $DOM->getElementsByTagName('th'); $Detail = $DOM->getElementsByTagName('td'); //#Get header name of the table foreach($Header as $NodeHeader) { $aDataTableHeaderHTML[] = trim($NodeHeader->textContent); } //print_r($aDataTableHeaderHTML); die(); //#Get row data/detail table without header name as key $i = 0; $j = 0; foreach($Detail as $sNodeDetail) { $aDataTableDetailHTML[$j][] = trim($sNodeDetail->textContent); $i = $i + 1; $j = $i % count($aDataTableHeaderHTML) == 0 ? $j + 1 : $j; } //print_r($aDataTableDetailHTML); die(); //#Get row data/detail table with header name as key and outer array index as row number for($i = 0; $i < count($aDataTableDetailHTML); $i++) { for($j = 0; $j < count($aDataTableHeaderHTML); $j++) { $aTempData[$i][$aDataTableHeaderHTML[$j]] = $aDataTableDetailHTML[$i][$j]; } } $aDataTableDetailHTML = $aTempData; unset($aTempData); print_r($aDataTableDetailHTML); die(); 您的代码工作得太辛苦,无法尝试将柱状数据保留在相应的行中。 为了让事情变得更容易,迭代行 (<tr>) 元素,然后访问给定行中的元素。 代码(演示)或(替代演示) $dom = new DOMDocument(); $dom->loadHTML($html); $result = []; foreach ($dom->getElementsByTagName('tr') as $row) { $result[] = [ 'name' => $row->getElementsByTagName('th')->item(0)->nodeValue, 'value' => $row->getElementsByTagName('td')->item(0)->nodeValue, ]; } var_export($result); 我这样做只是因为使用 explode 和 str_replace 很有趣——无需 PHP DOM 解析器.. 基本上使用 explode( '</tr>', $table ); 创建一个起始的 Main 空数组,并循环遍历它,在剥离不需要的内容后向其中添加临时数组(IE <tr> 和 trimming) <?php $table = <<<HTML <table> <tr> <th>Name</th> <th>Value</th> </tr> <tr> <td>Name One</td> <td>Value One</td> </tr><tr> <td>Name Two</td> <td>Value Two</td> </tr><tr> <td>Name Three</td> <td>Value Three</td> </tr> </table> HTML; $rows = explode( '</tr>', $table ); array_shift($rows); array_pop($rows); $main_arr = []; foreach ($rows as $row){ $name = trim( str_replace(['<td>', '<tr>'], '', explode('</td>', $row)[0] ) ); $value = trim( str_replace(['<td>', '<tr>'], '', explode('</td>', $row)[1] ) ); $tmp_arr = []; $tmp_arr['name'] = $name; $tmp_arr['value'] = $value; $main_arr[] = $tmp_arr; } print_r($main_arr); 你的输出应该是: Array ( [0] => Array ( [name] => Name One [value] => Value One ) [1] => Array ( [name] => Name Two [value] => Value Two ) [2] => Array ( [name] => Name Three [value] => Value Three ) ) 更新 这是执行相同操作的 PHP DOM 代码: <?php $DOM = new DOMDocument(); $DOM->loadHTML("<table> <tr> <th>Name</th> <th>Value</th> </tr> <tr> <td>Name One</td> <td>Value One</td> </tr><tr> <td>Name Two</td> <td>Value Two</td> </tr><tr> <td>Name Three</td> <td>Value Three</td> </tr> </table>"); $main_arr = []; $rows = $DOM->getElementsByTagName("tr"); for ($i = 0; $i < $rows->length; $i++) { $cols = $rows->item($i)->getElementsbyTagName("td"); $tmp_arr = []; if ($cols->item(0)->nodeValue){ $tmp_arr['name'] = $cols->item(0)->nodeValue; $tmp_arr['value'] = $cols->item(1)->nodeValue; $main_arr[] = $tmp_arr; } } print_r( $main_arr );

回答 2 投票 0

从所有 HTML 标签中删除所有不在白名单中的属性

所以,到目前为止我只能保留一个属性,但我试图将 class 和 id 属性保留在 HTML 标签中 代码: $string = '一些 所以,到目前为止我只能保留一个属性,但我试图将 class 和 id 属性保留在 HTML 标签中 代码: $string = '<div id="one-id" class="someClassName">Some text <a href="#" title="Words" id="linkId" class="classLink">link</a> with only the class and id attrtibutes./div>'; preg_replace("/<([a-z][a-z0-9]*)(?:[^>]*(\sclass=['\"][^'\"]*['\"]))?[^>]*?(\/?)>/i", '<$1$2$3>', $string); 输出: <div class="someClassName">Some text <a class="classLink">link</a> with only the class and id attrtibutes./div> 我试图从每个标签中删除除 class 和 id 属性之外的所有其他属性。 迭代 dom 中的所有节点,然后反向循环所有属性,以便您可以安全地修剪不在白名单中的属性。 (我修复了示例输入中 </div> 中的拼写错误。) 代码:(演示) $html = '<div id="one-id" class="someClassName">Some text <a href="#" title="Words" id="linkId" class="classLink">link</a> with only the class and id attrtibutes.</div>'; $dom = new DOMDocument(); $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); $xpath = new DOMXPath($dom); foreach ($xpath->query('//*') as $node) { for ($i = $node->attributes->length - 1; $i >= 0; --$i) { $attr = $node->attributes->item($i); if (!in_array($attr->name, ['id', 'class'])) { $node->removeAttribute($attr->name); } } } echo $dom->saveHTML(); 输出: <div id="one-id" class="someClassName">Some text <a id="linkId" class="classLink">link</a> with only the class and id attrtibutes.</div> ...实际上,XPath 并不是真正需要的,因为我们正在迭代 dom 中的每个节点。 (演示) $dom = new DOMDocument(); $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); foreach ($dom->getElementsByTagName('*') as $node) { for ($i = $node->attributes->length - 1; $i >= 0; --$i) { $attr = $node->attributes->item($i); if (!in_array($attr->name, ['id', 'class'])) { $node->removeAttribute($attr->name); } } } echo $dom->saveHTML();

回答 1 投票 0

iframe 仍然是个好主意吗?

我需要能够在浏览器中的网站上呈现文档。 (不是下载它)我知道解决这个问题的方法(无需向第三方软件付费)是 iram...

回答 2 投票 0

PHP DOMDocument 错误实体“nbsp”未定义

我使用 DOMDocument 来编辑一些 HTML 文件,但有些主题的名称空间中有。所以DOMDocument自动将空格改为%20然后就找不到了。 这就是错误的样子

回答 5 投票 0

我们可以在DomDocument中使用Array Element并嵌套xpath吗?

我正在使用以下代码 $page_data=array();//$title_links 是具有 url 的数组 $nodearr=数组(); foreach($title_links 为 $b_url) { $page_data[]= mycurl($b_url);//m...

回答 1 投票 0

如何将 DOMDocument 传递给子例程

我有一堆来自德国商业登记处的所谓“结构化数据”,它们以 xml 文件形式存在(一个文件始终保存一家公司的数据)。数据结构对应...

回答 1 投票 0

需要创建一个仅接受 a-z、A-Z 和空格中的字母的输入元素

在页面上创建一个输入元素,其中包含占位符“输入您的姓名”和 HTML 内页面上的 H2 标题。 此输入元素的目的是输入用户名,因此它应该只输入...

回答 1 投票 0

CSS 网格宽度动态内容,包括换行符

在我们的网站上,我们有一个简单的基于 BB 代码的编辑器来创建我们的帖子。为了能够创建基本网格,我添加了一个新标签,它是一个带有 display:grid 和 grid-template-columns 的简单包装器:

回答 1 投票 0

DOMDocument 从标签中删除监听器

我将 DOMDocument 与 HTML 一起使用,该 HTML 使用 Framework/Lib 并具有事件侦听器,但只是忽略具有“AT=@”的属性: $html = ' 我使用带有 HTML 的 DOMDocument,该 HTML 使用 Framework/Lib 并具有事件侦听器,但只是忽略具有“AT=@”的属性: $html = '<button @click="test()">ÁÈ</button>'; $dom = new DOMDocument(); libxml_use_internal_errors(true); $dom->loadHTML('<?xml encoding="utf-8" ?>' . $html); dump($dom); // Expected to happen - <button @click="test()">ÁÈ</button> // Actually resulted - <button>ÁÈ</button> 请注意,由于 DOMDocument,@click="test()" 已从字符串中删除。 您需要删除所有带有 @ 前缀的事件侦听器,为此,您可以使用 preg_replace 进行同样的操作。获取事件监听器的名称,同时借助正则表达式组号进行替换。 <?php $html = '<button @click="test()">ÁÈ</button>'; $html = preg_replace('/@([a-z]+)\=/i', '$1=', $html); echo $html; // rest of your code /* $dom = new DOMDocument(); libxml_use_internal_errors(true); $dom->loadHTML('<?xml encoding="utf-8" ?>' . $html); */ 现场演示

回答 1 投票 0

更改代码导致未捕获错误:调用成员函数 getElementsByTagName()

我有一个问题,因为可能网站的设计已经改变,我的脚本不起作用。 问题是 致命错误:未捕获错误:在...中的 null 上调用成员函数 getElementsByTagName()

回答 1 投票 0

使用 PHP 从背景图像样式属性中提取值

我有以下 HTML 代码: 我正在尝试提取图像 URL 并重新... 我有以下HTML代码: <div class="article__img has-caption" style="background-image: url('img/main/article-plug.png')" > 我正在尝试提取图像 URL 并将其替换为另一个(例如 img/main/article-plug.webp),但我被 XPath 查询困住了,不知道该怎么做。 提前感谢您的帮助! 那是我最后的代码(但它还没有返回任何东西): $domDocument = new DOMDocument(); $domDocument->loadHTML($article["DESCRIPTION"]); $domXPath = new DOMXPath($domDocument); $img = $domXPath->query('substring-before(substring-after(//div[@class=\'article__img has-caption\']/@style, "background-image: url(\'"), "\')")'); 使用 DOM 解析器从给定的 HTML 代码中提取图像 URL: $dom = new DOMDocument(); $dom->loadHTML($html); $divs = $dom->getElementsByTagName('div'); foreach ($divs as $div) { if ($div->getAttribute('class') === 'article__img has-caption') { $style = $div->getAttribute('style'); preg_match('/url\((.*?)\)/', $style, $matches); $imageUrl = $matches[1]; $newImageUrl = 'img/main/article-plug.webp'; $newStyle = str_replace($imageUrl, $newImageUrl, $style); $div->setAttribute('style', $newStyle); } } $newHtml = $dom->saveHTML(); echo $newHtml; // output: <div class="article__img has-caption" style="background-image: url('img/main/article-plug.webp')" > 此代码首先将 HTML 加载到 DOM 对象中,找到类为“article__img has-caption”的 div,从其样式属性中提取图像 URL,将其替换为新的图像 URL,更新 div 的样式属性,最后用更新后的图片 URL 生成新的 HTML。

回答 1 投票 0

为什么 DOMDocument 将两个 html 引用实体转换为实际引用?

我已经在这里待了半天了,所以现在是时候寻求帮助了。 我希望 DOMDocument 保留现有实体和 utf-8 字符。我现在认为这是不可能的...

回答 2 投票 0

DOMDocument 以一种奇怪的方式转换实体

我已经在这里待了半天了,所以现在是时候寻求帮助了。我确定我错过了一些简单的东西。 我希望 DOMDocument 保留现有实体和 utf-8 字符。 ...

回答 0 投票 0

回答 1 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.