繁体   English   中英

PHP 中 nodeValue 和 saveHTML() 的 DOMDocument() 问题

[英]DOMDocument() Problem with nodeValue and saveHTML() in PHP

我正在使用 Joomla CMS,我想在渲染中操作 DOM。 我想修改内联脚本以在页面加载时执行。 但是我遇到了一个谷歌地图脚本的问题,它的代码中有 HTML 标记,当我尝试使用nodeValue获取脚本的内容时,它会在第一次关闭</div>时将其切断; 我还尝试不修改任何内容,只需加载 HTML 然后使用saveHTML()保存它,同样的问题也会发生。

部分页面代码(page.html)

<!DOCTYPE html>
<html>
<head>
    <title>Page title</title>
    <script src="https://maps.googleapis.com/maps/api/js?key=XXXXXX" type="text/javascript"></script>
</head>
<body>
<header></header>
<main>
    <div class="wrapper">
        <div class="inner">
            <div class="map-container">
                <div class="google-map">
                    <div id="map-canvas95" class="map-canvas" style="width:100%;height:400px">
                        <script type="text/javascript">
                            //API demos Used(synchronous loading, info window,)
                            var myLatlng95 = new google.maps.LatLng(-11.926755,-77.05359);
                            var mapOptions95 = {
                                scrollwheel: false,
                                zoom: 15,
                                center: myLatlng95,
                                disableDefaultUI: true,
                                mapTypeId: google.maps.MapTypeId.ROADMAP,
                                mapTypeControl: true,
                                mapTypeControlOptions: {
                                    style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
                                    position: google.maps.ControlPosition.LEFT_TOP
                                },
                                panControl: true,
                                panControlOptions: {
                                    position: google.maps.ControlPosition.LEFT_CENTER
                                },
                                zoomControl: true,
                                zoomControlOptions: {
                                    style: google.maps.ZoomControlStyle.SMALL,
                                    position: google.maps.ControlPosition.LEFT_CENTER
                                },
                                scaleControl: true,
                                streetViewControl: true,
                                streetViewControlOptions: {
                                    position: google.maps.ControlPosition.LEFT_CENTER
                                }
                            };
                            var map95 = new google.maps.Map(document.getElementById('map-canvas95'), mapOptions95);

                            //Info Window
                            var contentString95 = '<div id="content">'+
                                '<div id="siteNotice"></div>'+
                                '<h1 id="firstHeading" class="firstHeading">Market Title</h1>'+
                                '<div id="bodyContent">'+
                                    '<p>Graphic Design. Lorem ipsum dolor sit amet, consectetur adipiscing elit. of Quisque ultricies vestibulum molestie.</p>'+
                                '</div>'+
                            '</div>';
                            var infowindow95 = new google.maps.InfoWindow({
                                content: contentString95,
                                maxWidth: 300
                            });
                            
                            //Marker
                            var marker95 = new google.maps.Marker({
                                position: myLatlng95,
                                map: map95,
                                title: 'Market Title'           });

                            //Event for open Info Window
                            google.maps.event.addListener(marker95, 'click', function() {
                                infowindow95.open(map95,marker95);
                            });
                        </script>
                    </div>
                </div>
            </div>
        </div>
    </div>
</main>
<footer></footer>
</body>
</html>

我的 DOM 脚本

    //$app = JFactory::getApplication('site'); for Joomla only
    //$body = $app->getBody(false);//for Joomla only
    $body = file_get_contents('page.html');
    $domDoc = new DOMdocument();
    libxml_use_internal_errors(true);
    $domDoc->loadHTML($body);
    libxml_clear_errors();
    $scripts =$domDoc->getElementsByTagName('script');
    $openScript = "\nwindow.addEventListener('DOMContentLoaded', function() {";
    $closeScript = "});\n";
    foreach ($scripts as $script) {
        $newScript = $openScript.$script->nodeValue.$closeScript;
        $script->nodeValue = (!empty($script->nodeValue)) ? $newScript : $script->nodeValue;
    }
    //$body = $domDoc->saveHTML();  for Joomla  
    //$app->setBody($body);for Joomla
    $domDoc->saveHTMLFIle('newDom.html');

在结果文件中,您可以看到脚本被剪切

<script>
  window.addEventListener('DOMContentLoaded', function() {    
  var contentString<?php echo $uniqid; ?> = '<div id="content">'+
  '<div id="siteNotice"></div>;
  });
</script>

就像这个谷歌地图脚本一样,我也看到了其他代码中包含 HTML 标记的脚本。 我该如何解决这个问题? 谢谢。

ext/dom不支持 HTML5 。 您可以使用HTML5-PHP库。 它将 HTML5 读入 XHTML DOM。

use \Masterminds\HTML5;

$html5 = new HTML5();
$document = $html5->loadHTML(getHTML());
$xpath = new DOMXpath($document);
// register namespace prefix for Xpath expressions 
$xpath->registerNamespace('xhtml', 'http://www.w3.org/1999/xhtml');

foreach ($xpath->evaluate('//xhtml:div[@class="google-map"]//xhtml:script') as $script) {
    $script->textContent = "\nwindow.addEventListener('DOMContentLoaded', function() {\n{$script->textContent}\n});\n";
}
echo $html5->saveHTML($document);

此外,不要使用DOMNode::$nodeValue而是使用DOMNode::$textContent来确保正确处理特殊字符。

暂无
暂无

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

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