【问题标题】:Failed loading XML:xmlParseCharRef: invalid xmlChar value加载 XML 失败:xmlParseCharRef:xmlChar 值无效
【发布时间】:2018-02-28 09:04:28
【问题描述】:

当我尝试导入 xml 文件时,它返回一个错误:

xmlParseCharRef:xmlChar 值 4" 无效,因为 xml 中的 $amp; <STOCKGROUP >NAME="ABC & Glass" RESERVEDNAME="">

这是我用来读取 xml 文件数据的代码

function add_product_type()
{
    print_r($_FILES);
    if (isset($_FILES['product_type_file']) && ($_FILES['product_type_file']['error'] == UPLOAD_ERR_OK)) {
        $use_errors = libxml_use_internal_errors(true);
        $response = simplexml_load_file($_FILES['product_type_file']['tmp_name']);
        print_r($response);
        foreach($response->BODY->IMPORTDATA as $key => $value) {
            foreach($value->REQUESTDATA->TALLYMESSAGE as $key => $values) {
                if (strstr("&", $values->STOCKGROUP->attributes())) {
                    $name = str_replace("&", "&", $values->STOCKGROUP->attributes());
                }
                else {
                    $name = $values->STOCKGROUP->attributes();
                }

                echo $name . ",";
            }
        }

        if ($response == false) {
            echo "Failed loading XML\n";
            foreach(libxml_get_errors() as $error) {
                echo "\t", $error->message;
            }
        }
    }
}

【问题讨论】:

  • 听起来您尝试读取的 XML 存在语法错误。你能发布一个示例文档吗?
  • xmlParseCharRef: invalid xmlChar value 4 这个错误发生
  • 不,请发布您尝试解析的 XML 数据的完整示例。错误消息中的 XML 看起来很破碎,但由于它是一个片段,因此无法分辨。

标签: php xml xml-parsing


【解决方案1】:

XML 没有 HTML 实体的概念。作为一个黑客,你可以decode the entities first

$html = html_entity_decode($file_contents, ENT_QUOTES, "utf-8");

然后尝试使用 XML 解析器解析 $html。只是希望它足够宽容,因为 HTML 仍然不是有效的 XML。

好消息是,您可以删除 if (strstr("&", hack,因为 html_entity_decode() 会处理这些问题。

【讨论】:

    【解决方案2】:

    您的 XML 示例与您收到错误并处理正常的数据不同,但这并不意味着您的代码是正确的。在 您的主循环,您使用$values->STOCKGROUP->attributes() 作为名称,但如果您对该值执行了print_r(),您将看到它带有所有属性值的列表,您的代码会将它们全部组合成一个字符串.

    SimpleXMLElement Object
    (
        [@attributes] => Array
            (
                [NAME] => Alluminium Section & Glass
                [RESERVEDNAME] => 
            )
    
    )
    

    如果您只想要<STOCKGROUP NAME="Alluminium Section & Glass" RESERVEDNAME=""> 的NAME 属性,请使用STOCKGROUP['NAME']。此外,不要只替换 &,而是使用 html_entity_decode() 转换名称中的任何字符。

    foreach($response->BODY->IMPORTDATA as $key => $value) {
        foreach($value->REQUESTDATA->TALLYMESSAGE as $key => $values) {
            $name = html_entity_decode((string)$values->STOCKGROUP['NAME']);    
            echo $name . ",";
        }
    }
    

    此代码与您提供的示例输出...

    Alluminium Section & Glass,
    

    更新: 检查正在加载的文件...

    $data = file_get_contents($_FILES['product_type_file']['tmp_name']);
    echo $data;
    $use_errors = libxml_use_internal_errors(true);
    $response = simplexml_load_string($data);
    echo $response->asXML();
    

    【讨论】:

    • print_r($response) 如何打印 SimpleXMLElement 对象([@attributes] => 数组([NAME] => 铝型材和玻璃 [RESERVEDNAME] =>))
    • 如果你想打印一个 SimpleXMLElement - 使用echo $response->asXML();
    • 当我使用 echo $response->asXML(); => 给我这个错误 -> 在布尔值中调用成员函数 asXML()
    • 这意味着 XML 不正确 - 但您提供的示例数据有效,因此这不是相同的数据或不是完整的数据。
    • 这是我的 xml 文件链接,您可以使用 => drive.google.com/file/d/16aI_-TE3TGb6N4K58mA2w9I3DLiuyeFQ/…
    猜你喜欢
    • 2020-03-19
    • 2012-12-08
    • 1970-01-01
    • 1970-01-01
    • 2020-03-18
    • 1970-01-01
    • 2018-01-02
    • 2019-08-15
    • 1970-01-01
    相关资源
    最近更新 更多