在这种情况下,建议使用名称空间解析无效xml响应的正确方法

时间:2011-07-13 12:59:26

标签: php xml xml-parsing xml-namespaces

我使用php来解析API的xml响应。这是示例回复 -

$xml = '<?xml version="1.0"?>
                    <q:response xmlns:q="http://api-url">
                        <q:impression>
                            <q:content>
                                <html>
                                        <meta name="HandheldFriendly" content="True">
                                        <meta name="viewport" content="width=device-width, user-scalable=no">
                                        <meta http-equiv="cleartype" content="on">
                                    </head>
                                    <body style="margin:0px;padding:0px;">
                                        <iframe scrolling="no" src="http://api-response-url/with/lots?of=parameters&somethingmore=someval" width="320px" height="50px" style="border:none;"></iframe>
                                    </body>
                                </html>
                            </q:content>
                            <q:cpc>0.02</q:cpc>
                        </q:impression>
                    </q:response>';

请注意以下几点 -

响应有一些无效的标记 -

  • <head>标记在<html>内开始不存在,但已关闭。
  • {li> <meta> <html>内的标记未关闭。
  • iframe的src属性包含一个由&分隔的多个参数的网址。因此,需要在$dom->loadXML();之前对此网址和任何其他可能的网址进行urlencoded编辑(请参阅下面的代码)。

要求

  • 我需要阅读<q:content></q:content>标签内的任何内容。
  • 我需要解析无效标记(正如我所知)并正确阅读内容。
  • url需要针对What characters do I need to escape in XML documents?中列出的字符进行编码。这需要用我正在遵循的当前逻辑来完成。

当前代码

所以,到目前为止,如果<q:content></q:content>标记内的内容是有效标记,我的代码可以正常工作 -

$dom = new DOMDocument;

$dom->loadXML($xml); // load the XML string defined above - works only if entire xml is valid 

$adHtml = "";

foreach ($dom->getElementsByTagNameNS('http://api-url', '*') as $element) 
{
    if($element->localName == "content")
    {
         $children = $element->childNodes; 

         foreach ($children as $child) 
         {
              $adHtml .= $child->ownerDocument->saveXML($child); 
         }

    }

}

echo $adHtml; //Have got necessary contents here

检查工作代码here(在iframe src中使用有效标记和单个参数)。

我现在在想什么

现在,在previous question -

中使用@hakre给出的解决方案
  • 我尝试使用DOMDocument::loadHTML(),它按照我的预期失败了。发出警告,例如 - Warning: DOMDocument::loadHTML(): Tag q:response invalid in Entity, line: 2

  • 转义What characters do I need to escape in XML documents?中列出的字符的字符串的特定部分。

问题

最后,如果我必须“逃避字符串的特定部分”(在我的情况下查找<q:content></q:content>之间的任何内容),在urlencode的答案中给出了什么,那么为什么不应该我首先寻找那些分隔符(<q:content></q:content>)并返回它?那么在这种情况下使用DOMDocument::loadXML()有什么好处?我想这是一个很常见的情况......

所以,我的问题是要求以及注意以下几点 - 给出的分数,最聪明的方法是什么?

1 个答案:

答案 0 :(得分:0)

在实施标准时,可以做出许多有效的选择。但是,违反标准没有有效的选择。您需要向那些向您发送这些数据的人员提供实施XML标准的一些有效选择。

其中一种选择是将HTML内容放在CDATA中。另一种方法是对HTML进行编码。

他们向你发送垃圾并将其称为XML是完全不可接受的。也许他们没有意识到它不是有效的XML,但事实并非如此。如果他们不相信你,那么你应该只是尝试在标准XML编辑器(如XMLspy)中打开“XML”。让他们作为第三方向XMLspy提出申诉,告诉他们他们的XML是否有效。

然后他们可以自由选择如何来生成有效的XML,并且您将被要求处理他们的选择。