解析后缺少PHP XML解析器CDATA关键字

时间:2018-06-29 03:19:54

标签: php dom simplexml

我有以下XML代码,我想读取这些代码并获取“ content”标签内的值。

"<?xml version='1.0' encoding='ISO-8859-1'?>
                <ad modelVersion='0.9'>
                    <richmediaAd>
                        <content>
                            <![CDATA[<script src=\"mraid.js\"></script> 
                                <div class=\"celtra-ad-v3\"> 
                                    <img src=\"data: image/png, celtra\" style=\"display: none\"onerror=\"(function(img){ varparams={ 'channelId': '45f3f23c','clickUrl': 'http%3a%2f%2fexamplehost.com%3a53766%2fCloudMobRTBWeb%2fClickThroughHandler.ashx%3fadid%3de6983c95-9292-4e16-967d-149e2e77dece%26cid%3d352%26crid%3d850'};varreq=document.createElement('script');req.id=params.scriptId='celtra-script-'+(window.celtraScriptIndex=(window.celtraScriptIndex||0)+1);params.clientTimestamp=newDate/1000;req.src=(window.location.protocol=='https: '?'https': 'http')+': //ads.celtra.com/e7f5ce18/mraid-ad.js?';for(varkinparams){req.src+='&amp;'+encodeURIComponent(k)+'='+encodeURIComponent(params[ k ]); }img.parentNode.insertBefore(req, img.nextSibling);})(this);\"/> 
                                </div>]]>
                        </content>
                        <width>320</width>
                        <height>50</height>
                    </richmediaAd>
                </ad>"

我尝试了2种方法(SimpleXML和DOM)。我设法获得了该值,但发现缺少关键字“ CDATA”。我在“内容”标签中得到的是:

 <script src="mraid.js"></script> 
     <div class="celtra-ad-v3"> 
         <img src="data: image/png, celtra" style="display: none"onerror="(function(img){ varparams={ 'channelId': '45f3f23c','clickUrl': 'http%3a%2f%2fexamplehost.com%3a53766%2fCloudMobRTBWeb%2fClickThroughHandler.ashx%3fadid%3de6983c95-9292-4e16-967d-149e2e77dece%26cid%3d352%26crid%3d850'};varreq=document.createElement('script');req.id=params.scriptId='celtra-script-'+(window.celtraScriptIndex=(window.celtraScriptIndex||0)+1);params.clientTimestamp=newDate/1000;req.src=(window.location.protocol=='https: '?'https': 'http')+': //ads.celtra.com/e7f5ce18/mraid-ad.js?';for(varkinparams){req.src+='&amp;'+encodeURIComponent(k)+'='+encodeURIComponent(params[ k ]); }img.parentNode.insertBefore(req, img.nextSibling);})(this);"/> 
     </div>

我知道解析器试图通过删除CDATA来“美化” XML。但是我想要的只是带有“ CDATA”标签的原始数据。有什么办法可以做到这一点? 感谢您的帮助。

以下是我的两种方法供您参考: 方法1:

$type = simplexml_load_string($response['adm']) or die("Error: Cannot create object");
$data = $type->richmediaAd[0]->content;
Yii::warning((string) $data);
Yii::warning(strpos($data, 'CDATA'));

方法2:

$doc = new \DOMDocument();
$doc->loadXML($response['adm']);
$richmediaAds = ($doc->getElementsByTagName("richmediaAd"));
foreach($richmediaAds as $richmediaAd){
    $contents = $richmediaAd->getElementsByTagName("content");
    foreach($contents as $content){
         Yii::warning($content->nodeValue);
    }
}

1 个答案:

答案 0 :(得分:1)

如果可以的话,我会改善这一点,但是您可以显式地指定内容元素的“ CDATA节”节点,并使用$doc->saveXML( $node )作为该节点的参数来获取确切的XML元素结构。

$doc = new \DOMDocument();
$doc->loadXML( $xml );

$xpath = new \DOMXPath( $doc );
$nodes = $xpath->query( '/ad/richmediaAd/content');

foreach( $nodes[0]->childNodes as $node )
{
  if( $node->nodeType === XML_CDATA_SECTION_NODE )
  {
    echo $doc->saveXML( $node ); // string content
  }
}

编辑:如果找不到CDATA,您可能希望支持一些冗余。


没有XPATH

$doc = new \DOMDocument();
$doc->loadXML( $xml );
$doc->normalize();

foreach( $doc->getElementsByTagName('content')->item(0)->childNodes as $node )
{
  if( $node->nodeType === XML_CDATA_SECTION_NODE )
  {
    echo $doc->saveXML( $node ); // string content
  }
}