【问题标题】:Namespace prefix isn't defined. How can I define it automatically/ignore error?未定义命名空间前缀。如何自动定义它/忽略错误?
【发布时间】:2016-07-11 01:38:30
【问题描述】:

我制作了一个解析 XML 文件的 PHP 脚本,当我尝试解析它时,出现错误:

2: DOMDocument::load(): 命名空间前缀 edf 用于表示信息是 未定义在 /users/zzz/testing/meta.xml, 行:2

我一直在寻找解决方案,但找不到任何解决方案,所以我在这里发布。如您所见,我正在使用DOMDocument 类。

我解析 XML 的代码如下:

$dom = new DOMDocument();
$metaXML = $dom->load($path."/meta.xml");

我敢肯定,路径和一切都是正确的。当我删除前缀时,它工作正常。 XML 看起来像:

<meta>
    <info gamemodes="race" type="map" edf:represent="false"></info>
</meta>

edf:represent="false" 会导致错误。 我不想手动删除 edf 命名空间前缀,因为这不是我要解析的唯一 XML 文件。有数百个,而且这个数字还在上升。

所以,我的问题是,我怎样才能忽略这个错误(仅适用于 XML 命名空间的东西)或者我怎样才能通过 DOMDocument 类定义/删除命名空间前缀?

【问题讨论】:

    标签: php xml xml-parsing xml-namespaces


    【解决方案1】:

    这是一个警告而不是错误。所以 XML 仍然可以使用,但是它被破坏了。最好的解决方案是修复 XML - 定义命名空间。

    定义命名空间不会自动工作。命名空间前缀只是一个别名,实际的命名空间是 xmlns 属性的值。别名仅对元素及其后代有效。必须修复生成 XML 的脚本/应用程序,以便添加命名空间定义。

    <meta xmlns:edf="urn:example">
        <info gamemodes="race" type="map" edf:represent="false"></info>
    </meta>
    

    解析器将解析命名空间。您可以将“edf:represent”读作“{urn:example}represent”。

    但是,您可以使用 libxml_use_internal_errors() 阻止解析错误和警告。

    $xml = <<<'XML'
    <meta>
        <info gamemodes="race" type="map" edf:represent="false"></info>
    </meta>
    XML;
    
    libxml_use_internal_errors(TRUE);
    
    $dom = new DOMDocument();
    $dom->loadXml($xml);
    
    echo $dom->saveXml();
    

    输出:

    <?xml version="1.0"?>
    <meta>
        <info gamemodes="race" type="map" represent="false"/>
    </meta>
    

    使用libxml_get_errors(),您可以实现自己的错误处理。

    正如您在输出中看到的,XML 解析器删除了命名空间前缀。这意味着“represent”现在是一个没有命名空间的属性,它改变了它的身份。请务必小心,represent{urn:example}represent 是两个不同的名称,您会丢失相关的上下文信息。

    【讨论】:

    • 谢谢,我不知道 libxml_use_internal_errors 函数。现在可以了。
    【解决方案2】:

    XML 文件本身不是namespace-well-formed,因为它使用了未声明的命名空间前缀。要么删除未声明的命名空间前缀,要么声明它,例如:

    <meta xmlns:edf="http://www.example.com/">
        <info gamemodes="race" type="map" edf:represent="false"></info>
    </meta>
    

    更新: 您无法使用 XML 库执行此操作,因为 XML 格式不正确。您必须手动执行或以文本方式而不是 XML 以编程方式对文件进行操作。一旦您将文本变成格式良好的 XML,您就可以使用标准 XML 库来处理它。

    这是@Daniel 提出的基于文本的程序化编辑建议:


    如果您需要跨多个文件更正此问题,请考虑使用“sed”之类的工具将您的元标记替换为更正后的版本。例如,要将文件夹中的所有 &lt;meta 实例替换为 &lt;meta xmlns:edf="http://www.example.com/"。你可以使用这个命令

    sed -i -- 's/<meta/<meta\ xmlns\:edf\=\"http\:\/\/www.example.com\/\"/g' *
    

    有关如何使用 sed 的更多信息,请参阅 https://unix.stackexchange.com/questions/112023/how-can-i-replace-a-string-in-a-files


    格式良好的 XML 应该始终使用 XML 解析器进行解析,但有时像上面这样的快速和肮脏的修复可以帮助我们到达那里。

    另见:

    【讨论】:

    • 如何使用 PHP 自动定义或删除它?就像我说的,我有太多这样的XML文件,我不想一个一个地改变。
    • 看到更新嗯,好的,我明白了。但是有什么方法可以检查 XML 是否“格式不正确”?因为现在,它返回一个错误并退出程序。我尝试使用 if 语句 if(!metaXML) { ... },但它仍然返回错误。
    • 检查 XML 是否格式正确的方法就是解析它。如果格式不正确,您将根据定义得到错误。
    猜你喜欢
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    相关资源
    最近更新 更多