当前位置: 首页 > 面试题库 >

在使用DOMDocument函数进行处理之前,修复PHP中格式错误的XML

訾安邦
2023-03-14
问题内容

我需要将XML文档从外部源加载到PHP中。XML未声明其编码,并且包含非法字符,如&。如果尝试直接在浏览器中加载XML文档,则在用PHP加载文件时也会收到诸如“在文本内容中发现无效字符”之类的错误消息,并且还会收到很多警告,例如:xmlParseEntityRef: no name in EntityInput is not proper UTF-8, indicate encoding ! Bytes: 0x9C 0x31 0x21 0x3C

显然,XML格式不正确,并且包含应转换为XML实体的非法字符。

这是因为XML提要由许多其他用户提供的数据组成,并且很明显,在我获得它之前,尚未对其进行验证或重新格式化。

我已经与XML feed的供应商进行了交谈,他们说他们正试图让内容提供商对其进行分类,但这似乎很愚蠢,因为他们应该首先验证输入。

我基本上需要修复XML,以纠正任何编码错误并将任何非法字符转换为XML实体,以便在使用PHP的DOMDocument函数时XML加载问题。

我的代码当前如下所示:

  $feedURL = '3704017_14022010_050004.xml';
  $dom = new DOMDocument();
  $dom->load($feedURL);

显示编码问题的XML文件示例(单击下载):feed.xml

包含未转换为XML实体的字符的示例XML:

<?xml version="1.0"?>
<feed>
<RECORD>
<ID>117387</ID>
<ADVERTISERNAME>Test</ADVERTISERNAME>
<AID>10544740</AID>
<NAME>This & This</NAME>
<DESCRIPTION>For one day only this is > than this.</DESCRIPTION>
</RECORD>
</feed>

问题答案:

尝试使用Tidy库,该库可用于清除不良的HTML和XML
http://php.net/manual/zh/book.tidy.php

一个纯PHP解决方案,用于修复如下所示的一些XML:

<?xml version="1.0"?>
<feed>
<RECORD>
<ID>117387</ID>
<ADVERTISERNAME>Test < texter</ADVERTISERNAME>
<AID>10544740</AID>
<NAME>This & This</NAME>
<DESCRIPTION>For one day only this is > than this.</DESCRIPTION>
</RECORD>
</feed>

将是这样的:

  function cleanupXML($xml) {
    $xmlOut = '';
    $inTag = false;
    $xmlLen = strlen($xml);
    for($i=0; $i < $xmlLen; ++$i) {
        $char = $xml[$i];
        // $nextChar = $xml[$i+1];
        switch ($char) {
        case '<':
          if (!$inTag) {
              // Seek forward for the next tag boundry
              for($j = $i+1; $j < $xmlLen; ++$j) {
                 $nextChar = $xml[$j];
                 switch($nextChar) {
                 case '<':  // Means a < in text
                   $char = htmlentities($char);
                   break 2;
                 case '>':  // Means we are in a tag
                   $inTag = true;
                   break 2;
                 }
              }
          } else {
             $char = htmlentities($char);
          }
          break;
        case '>':
          if (!$inTag) {  // No need to seek ahead here
             $char = htmlentities($char);
          } else {
             $inTag = false;
          }
          break;
        default:
          if (!$inTag) {
             $char = htmlentities($char);
          }
          break;
        }
        $xmlOut .= $char;
    }
    return $xmlOut;
  }

这是一个简单的状态机,它指示我们是否在标记中,如果没有,则使用htmlentities编码文本。

值得注意的是,这将占用大文件的内存,因此您可能需要将其重写为流插件或预处理器。



 类似资料:
  • 问题内容: 我正在获取JSON格式和唯一可用格式的数据提要。在PHP中,我正在使用json_decode解码JSON,但此操作已中断,并且我发现JSON是在某些地方生成的,其昵称用双引号引起来。我使用以下方法验证了这一点:http : //jsonformatter.curiousconcept.com 我无法控制数据的创建,但是当这种格式出现时,我必须处理它。解析后的数据将被放入MySQL TA

  • 本文向大家介绍PHP错误处理函数,包括了PHP错误处理函数的使用技巧和注意事项,需要的朋友参考一下 在 PHP 中,默认的错误处理很简单。一条错误消息会被发送到浏览器,这条消息带有文件名、行号以及描述错误的消息。 PHP 错误处理 在创建脚本和 Web 应用程序时,错误处理是一个重要的部分。如果您的代码缺少错误检测编码,那么程序看上去很不专业,也为安全风险敞开了大门。 本教程介绍了 PHP 中一些

  • 问题内容: 我在Swift中使用,需要获取更好的错误消息。 在调试描述中(例如),我可以看到诸如“给定数据不是有效的JSON”之类的消息,但是我需要知道的是,而不是网络错误(例如)。 我尝试将其强制转换为,但这似乎并未显示更多信息。我当然不需要字符串-甚至错误代码也比这有用得多… 问题答案: 切勿在解码块中打印。这将返回一个毫无意义的通用错误消息。始终打印实例。然后,您会得到所需的信息。 或针对

  • Promise 链在错误(error)处理中十分强大。当一个 promise 被 reject 时,控制权将移交至最近的 rejection 处理程序(handler)。这在实际开发中非常方便。 例如,下面代码中所 fetch 的 URL 是错的(没有这个网站),.catch 对这个 error 进行了处理: fetch('https://no-such-server.blabla') // re

  • 问题内容: 我正在使用具有以下功能的simplehtmldom: 我这样使用它: 有时,URL可能只是无效的,我想对此进行处理。我以为我可以使用try and catch,但是这没有用,因为它不会抛出异常,它只是给出了这样的php警告: 第39行在上面的代码中。 我如何正确处理此错误,我可以只使用普通条件,它看起来不像返回布尔值。 谢谢大家的帮助 更新资料 这是一个好的解决方案吗? 问题答案: 这

  • 问题内容: 根据对此答案的评论,有可能通过关机功能来捕获致命错误,而使用不能捕获该错误。 但是,我无法确定如何确定是由于致命错误还是由于脚本到达末尾而导致关机。 另外,调试回溯函数似乎在关闭函数中已失效,因此对于记录发生致命错误的堆栈跟踪而言,它毫无价值。 所以我的问题是:对致命错误(尤其是未定义的函数调用)做出反应的同时保持创建适当回溯能力的最佳方法是什么? 问题答案: 这对我有用: 但是,您可