未定义命名空间前缀。如何自动定义/忽略错误?

时间:2016-03-23 16:29:42

标签: php xml xml-parsing xml-namespaces

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

  

2:DOMDocument :: load():用于表示信息的命名空间前缀edf   没有定义   /users/zzz/testing/meta.xml,   line: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类定义/删除命名空间前缀?

2 个答案:

答案 0 :(得分:3)

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

定义namesapce将无法自动运行。名称空间前缀只是别名,实际名称空间是xmlns属性的值。别名仅对元素及其后代有效。必须修复生成XML的脚本/应用程序,以便添加命名空间定义。

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

解析器将解析命名空间。您可以将“edf:represent”视为“{urn:example}表示”。

但是,您可以使用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{urn:example}represent是两个不同的名称,您会丢失相关的上下文信息。

答案 1 :(得分:2)

XML文件本身格式不正确,因为它使用未声明的命名空间前缀。删除未声明的名称空间前缀,或声明它,例如:

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

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

以下是@Daniel编写的基于文本的编辑建议:

如果您需要纠正许多文件中缺少格式化的问题,请考虑使用“sed”之类的工具将您的元标记替换为更正后的版本。例如,要在文件夹中替换<meta的所有<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,但有时像上面那样快速而肮脏的修复可以帮助我们实现目标。