PHP - 处理XML无效PHP - 处理XML无效(PHP - Processing Inva

2019-05-12 03:45发布

我使用的SimpleXML加载一些XML文件(我没有写/提供并不能真正改变的格式)。

偶尔(例如,一个或两个文件每50左右),他们不逃避任何特殊字符(主要是及,但有时其他随机无效的东西太多)。 这将创建和问题,因为SimpleXML的用php,只不过没有了,我真的不知道来处理解析无效的XML什么好办法。

我的第一个想法是预处理XML作为一个字符串,并把所有的字段作为CDATA所以它会工作,但由于某种原因敬虔我需要处理XML把所有的数据在属性字段。 因此,我不能使用CDATA想法。 的XML之中的一个示例:

 <Author v="By Someone & Someone" />

最新最好的方法来处理这个来代替从XML的所有无效字符之前,我在用SimpleXML加载它?

Answer 1:

你需要的是一些将使用的libxml的内部错误定位无效字符,并相应地逃离他们。 下面是我怎么会写一个样机。 看看结果libxml_get_errors()的错误信息。

function load_invalid_xml($xml)
{
    $use_internal_errors = libxml_use_internal_errors(true);
    libxml_clear_errors(true);

    $sxe = simplexml_load_string($xml);

    if ($sxe)
    {
        return $sxe;
    }

    $fixed_xml = '';
    $last_pos  = 0;

    foreach (libxml_get_errors() as $error)
    {
        // $pos is the position of the faulty character,
        // you have to compute it yourself
        $pos = compute_position($error->line, $error->column);
        $fixed_xml .= substr($xml, $last_pos, $pos - $last_pos) . htmlspecialchars($xml[$pos]);
        $last_pos = $pos + 1;
    }
    $fixed_xml .= substr($xml, $last_pos);

    libxml_use_internal_errors($use_internal_errors);

    return simplexml_load_string($fixed_xml);
}


Answer 2:

我认为workaroung创建compute_position功能将会使处理前的XML字符串持平。 重写发表乔什代码:

function load_invalid_xml($xml)
{
    $use_internal_errors = libxml_use_internal_errors(true);
    libxml_clear_errors(true);

    $sxe = simplexml_load_string($xml);

    if ($sxe)
    {
        return $sxe;
    }

    $fixed_xml = '';
    $last_pos  = 0;

    // make string flat
    $xml = str_replace(array("\r\n", "\r", "\n"), "", $xml);

    // get file encoding
    $encoding = mb_detect_encoding($xml);

    foreach (libxml_get_errors() as $error)
    {
        $pos = $error->column;
        $invalid_char = mb_substr($xml, $pos, 1, $encoding);
        $fixed_xml .= substr($xml, $last_pos, $pos - $last_pos) . htmlspecialchars($invalid_char);
        $last_pos = $pos + 1;
    }
    $fixed_xml .= substr($xml, $last_pos);

    libxml_use_internal_errors($use_internal_errors);

    return simplexml_load_string($fixed_xml);
}

我已经添加了编码的东西becose我有问题,从字符串获得字符数组简单[指数]的方式。

这一切都应该工作,但是,不知道为什么,我已经看到了$错误 - >列给了我不同的数字比它应该。 试图通过简单的XML里面添加一些无效字符,并检查它会返回什么价值来调试这一点,但它没有运气。 希望有人能告诉我什么是错的这种做法。



文章来源: PHP - Processing Invalid XML