繁体   English   中英

使用 DomDocument 从文件中分离 HTML、CSS 和 JavaScript

[英]Separate HTML, CSS, and JavaScript from file with DomDocument

我正在使用 PHP 加载远程文件,然后尝试使用DomDocument对其进行解析。 该文件包含 HTML、CSS(在style标签内)和 JavaScript(在script标签内)。 然后我通过将htmlcssjs分别传递给正在解析它的 function 来加载它。 这个想法是我可以使用核心 WordPress 方法在适当的位置显示这些。

这是我设法得到的最接近的:

libxml_use_internal_errors( true );
$document = wp_remote_retrieve_body( $response ); // this is the remote HTML file
// create a new DomDocument object
$html = new DOMDocument( '1.0', 'UTF-8' );
// load the HTML into the DomDocument object (this would be your source HTML)
$html->loadHTML( $document, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );
if ( 'html' === $part ) {
    $xpath  = new DOMXPath( $html );
    $remove = $xpath->query( "//*[style or script]" );
    foreach ( $remove as $node ) {
        $node->parentNode->removeChild($node);
    }
} elseif ( 'css' === $part ) {
    $xpath  = new DOMXPath( $html );
    $remove = $xpath->query( "//*[not(self::style)]" );
    foreach ( $remove as $node ) {
        $node->parentNode->removeChild($node);
    }
} elseif ( 'js' === $part ) {
    $xpath  = new DOMXPath( $html );
    $remove = $xpath->query( "//*[not(self::script)]" );
    foreach ( $remove as $node ) {
        $node->parentNode->removeChild($node);
    }
}

ob_start();
echo $html->saveHTML();
$output = ob_get_contents();
ob_end_clean();

这会导致几个问题:

  1. 在 CSS 和 JavaScript output 上,它保留了stylescript标签,我正试图弄清楚如何删除它。
  2. On the HTML output, it keeps the <.DOCTYPE html PUBLIC "-//W3C//DTD HTML 4:0 Transitional//EN" "http.//www.w3.org/TR/REC-html40/loose.dtd"><html><head></head><body>我也想删除它。

我不确定我是否需要从另一个方向着手,或者我是否只需要一个小东西来移除这些包装元素。 但是我很难让xpath与我想要保留的元素相关联,而不是我想要删除的元素,这就是我最终的结果。

对于您的html案例,您可以只保存<body>元素,而不是保存整个 DOMDocument。

libxml_use_internal_errors( true );
$document = wp_remote_retrieve_body( $response ); // this is the remote HTML file
// create a new DomDocument object
$html = new DOMDocument( '1.0', 'UTF-8' );
// load the HTML into the DomDocument object (this would be your source HTML)
$html->loadHTML( $document, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );
if ( 'html' === $part ) {
    // get all <body> elements
    $body_elements = $html->getElementsByTagName( 'body' );
    // it is to be assumed that there is only one <body> element.
    $body = $body_elements->item( 0 );
    // get the HTML contained within that body element
    $output = $body->ownerDocument->saveHTML( $body );
} else {
    // ...
}

对于 CSS 和 JS 元素,我不确定为什么您需要在没有包含标签的情况下只获取它们的内部内容,但是与我们刚刚对$body所做的类似方法将起作用:1. select 元素,2 . foreach循环遍历元素数组, 3. 获取每个元素的保存内部(我相信但不确定这将是一个DOMText对象)并连接这些字符串以创建最终的$output变量。

CSS 和 JS 的另一种方法:采用现有方法的<script><tag>元素集群,将它们插入空白DOMDocument<head>以将其包含的<head>保存为 HTML 字符串,然后将其排入队列通过 WordPress 的wp_enqueue_scripts钩子上的匿名 function 字符串:

/**
 * https://stackoverflow.com/questions/66361476/separate-html-css-and-javascript-from-file-with-domdocument?newreg=231eb52469c14d8c9c45ee9969df031a
 */
function wpse_66361476_alert() {
    $output = "<script>alert('hello');</script>"; // demonstration content
    add_action(
        'wp_enqueue_scripts',
        function() use ($output) {
            echo $output;
        }
    );
}
add_action('init', 'wpse_66361476_alert');

如果您不控制您正在输出的 CSS 和 JS(和 HTML),那么这种方法是危险的。 无论您在此处加载什么,iframe 可能会更好。

如果您的主机尚未使用前端缓存,为了提高页面加载速度,您可能需要考虑使用 WordPress 的缓存功能缓存已解析的元素。 这是一个简短的概述 与您的托管服务提供商交谈,看看他们是否有具体建议。

问题在于 DomNode。 查看DOMDocument 从 HTML 源代码中删除脚本标签,它应该让您了解如何修改代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM