使用 DomDocument 将 HTML、CSS 和 JavaScript 从文件中分离出来
Separate HTML, CSS, and JavaScript from file with DomDocument
我正在使用 PHP 加载远程文件,然后尝试使用 DomDocument
解析它。该文件包含 HTML、CSS(在 style
标签内)和 JavaScript(在 script
标签内)。然后我通过将 html
或 css
或 js
传递到解析它的函数中来单独加载它。我的想法是,我可以使用核心 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();
这会导致一些问题:
- 在 CSS 和 JavaScript 输出中,它保留了
style
或 script
标签,我正在想办法删除它。
- 在 HTML 输出中,它保留了
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"><html><head></head><body>
,我也想将其删除。
我不确定是否需要朝另一个方向进行,或者我是否只需要一个小东西来移除这些包装元素。但是我很难让 xpath
与我想要保留的元素相关联,而不是与我想要删除的元素相关联,这就是我最终达到的结果。
问题出在 DomNode 上。查看 DOMDocument remove script tags from HTML source,这会让您了解如何修改代码。
对于您的 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 元素,我不确定为什么你只需要获取它们的内部内容而不需要包含标签,但是与我们刚刚对 [=14 所做的类似的方法=] 会起作用:1. select 元素,2. foreach
遍历元素数组,3. 获取每个元素的内部保存(我 相信 但是我不确定这将是一个 DOMText
对象)并连接这些字符串以创建最终的 $output
变量。
CSS 和 JS 的另一种方法:采用现有方法的 <script>
或 <tag>
元素簇,将它们插入空白 DOMDocument
's <head>
to save their containing <head>
as an HTML string, and then enqueue that string via an anonymous function on WordPress' wp_enqueue_scripts
勾:
/**
*
*/
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 的缓存功能来缓存已解析的元素。 Here's a short overview;与您的托管服务提供商联系,看看他们是否有具体建议。
我正在使用 PHP 加载远程文件,然后尝试使用 DomDocument
解析它。该文件包含 HTML、CSS(在 style
标签内)和 JavaScript(在 script
标签内)。然后我通过将 html
或 css
或 js
传递到解析它的函数中来单独加载它。我的想法是,我可以使用核心 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();
这会导致一些问题:
- 在 CSS 和 JavaScript 输出中,它保留了
style
或script
标签,我正在想办法删除它。 - 在 HTML 输出中,它保留了
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"><html><head></head><body>
,我也想将其删除。
我不确定是否需要朝另一个方向进行,或者我是否只需要一个小东西来移除这些包装元素。但是我很难让 xpath
与我想要保留的元素相关联,而不是与我想要删除的元素相关联,这就是我最终达到的结果。
问题出在 DomNode 上。查看 DOMDocument remove script tags from HTML source,这会让您了解如何修改代码。
对于您的 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 元素,我不确定为什么你只需要获取它们的内部内容而不需要包含标签,但是与我们刚刚对 [=14 所做的类似的方法=] 会起作用:1. select 元素,2. foreach
遍历元素数组,3. 获取每个元素的内部保存(我 相信 但是我不确定这将是一个 DOMText
对象)并连接这些字符串以创建最终的 $output
变量。
CSS 和 JS 的另一种方法:采用现有方法的 <script>
或 <tag>
元素簇,将它们插入空白 DOMDocument
's <head>
to save their containing <head>
as an HTML string, and then enqueue that string via an anonymous function on WordPress' wp_enqueue_scripts
勾:
/**
*
*/
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 的缓存功能来缓存已解析的元素。 Here's a short overview;与您的托管服务提供商联系,看看他们是否有具体建议。