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

GTX*_*GTX 5 php xml xml-namespaces xml-parsing

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

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

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

我的解析 XML 的代码如下所示:

$dom = new DOMDocument();
$metaXML = $dom->load($path."/meta.xml");
Run Code Online (Sandbox Code Playgroud)

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

<meta>
    <info gamemodes="race" type="map" edf:represent="false"></info>
</meta>
Run Code Online (Sandbox Code Playgroud)

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

所以,我的问题是,如何忽略此错误(仅适用于 XML 命名空间)或者如何通过DOMDocument类定义/删除命名空间前缀?

ThW*_*ThW 3

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

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

<meta xmlns:edf="urn:example">
    <info gamemodes="race" type="map" edf:represent="false"></info>
</meta>
Run Code Online (Sandbox Code Playgroud)

解析器将解析名称空间。您可以将“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();
Run Code Online (Sandbox Code Playgroud)

输出:

<?xml version="1.0"?>
<meta>
    <info gamemodes="race" type="map" represent="false"/>
</meta>
Run Code Online (Sandbox Code Playgroud)

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

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