问题 我如何告诉DOMDocument-> load()我想要它使用什么编码?


我从其他地方搜索和处理XML文件,并且需要 用一些XSLT转换它们。没问题。使用PHP5和DOM 图书馆,一切都很快。工作得很好,到现在为止。今天,时髦 字符在XML文件中 - 来自Word的“智能”引用,它看起来 喜欢。无论如何,DOMDocument-> load抱怨他们,说 它们不是UTF-8,而是指定编码。

请注意,这些XML文件中未指定编码。如果我 将'encoding =“iso-8859-1”'添加到标题中,它可以正常工作。摩擦是 我无法控制这些XML文件。

将文件读入字符串,修改其标题并将其写回 到另一个地方似乎是我唯一的选择,但我更愿意这样做 它根本不必使用XML文件的临时副本。是 有没有办法简单地告诉解析器解析它们就好像它们一样 ISO-8859-1?


5039
2017-08-13 00:45


起源



答案:


这对你有用吗?

$doc = new DOMDocument('1.0', 'iso-8859-1');
$doc->load($xmlPath);

编辑: 由于看起来这不起作用,所以你可以做的是类似于你现有的方法但没有临时文件。仅使用标准IO操作从源中读取XML文件(file_get_contents() 或某事),然后对您需要的编码执行任何更改(iconv() 要么 utf8_decode())然后使用 loadXML()

$myXMLString = file_get_contents($xmlPath);
$myXMLString = utf8_decode($myXMLString);
$doc = new DOMDocument('1.0', 'iso-8859-1');
$doc->loadXML($myXMLString);

9
2017-08-13 00:48



试过这个 - 它似乎没有影响加载的文档 - 从我的阅读,我很确定编码被load()调用重置 - Loki


答案:


这对你有用吗?

$doc = new DOMDocument('1.0', 'iso-8859-1');
$doc->load($xmlPath);

编辑: 由于看起来这不起作用,所以你可以做的是类似于你现有的方法但没有临时文件。仅使用标准IO操作从源中读取XML文件(file_get_contents() 或某事),然后对您需要的编码执行任何更改(iconv() 要么 utf8_decode())然后使用 loadXML()

$myXMLString = file_get_contents($xmlPath);
$myXMLString = utf8_decode($myXMLString);
$doc = new DOMDocument('1.0', 'iso-8859-1');
$doc->loadXML($myXMLString);

9
2017-08-13 00:48



试过这个 - 它似乎没有影响加载的文档 - 从我的阅读,我很确定编码被load()调用重置 - Loki


我还没有找到设置默认编码的方法,但是 也许 在这种情况下,恢复模式是可行的。
当libxml遇到编码错误并且没有显式设置编码时,它会从unicode / utf8切换到latin1并继续解析文档。但是在解析器上下文中属性 wellFormed 设置为0 / false。 PHP的DOM扩展认为文档有效 wellFormed 是真的 要么 DOMDocument对象的属性 recover 是真的。

<?php
// german Umlaut ä in latin1 = 0xE4
$xml = '<foo>'.chr(0xE4).'</foo>';

$doc = new DOMDocument;
$b = $doc->loadxml($xml);
echo 'with doc->recover=false(default) : ', ($b) ? 'success':'failed', "\n";

$doc = new DOMDocument;
$doc->recover = true;
$b = $doc->loadxml($xml);
echo 'with doc->recover=true : ', ($b) ? 'success':'failed', "\n";

版画

Warning: DOMDocument::loadXML(): Input is not proper UTF-8, indicate encoding !
Bytes: 0xE4 0x3C 0x2F 0x66 in Entity, line: 1 in test.php on line 6
with doc->recover=false(default) : failed

Warning: DOMDocument::loadXML(): Input is not proper UTF-8, indicate encoding !
Bytes: 0xE4 0x3C 0x2F 0x66 in Entity, line: 1 in  test.php on line 11
with doc->recover=true : success

您仍然会收到警告消息(可以使用@ $ doc-> load()来抑制),它也会显示在 内部libxml错误 (解析器从utf8切换到latin1时只有一次)。此特定错误的错误代码为9(XML_ERR_INVALID_CHAR)。

<?php
$xml = sprintf('<foo>
    <ae>%s</ae>
    <oe>%s</oe>
    &
</foo>', chr(0xE4),chr(0xF6));

libxml_use_internal_errors(true);
$doc = new DOMDocument;
$doc->recover = true;
libxml_clear_errors();
$b = $doc->loadxml($xml);
$invalidCharFound = false;
foreach(libxml_get_errors() as $error) {
    if ( 9==$error->code && !$invalidCharFound ) {
        $invalidCharFound = true;
        echo "found invalid char, possibly harmless\n";
    }
    else {
        echo "hm, that's probably more severe: ", $error->message, "\n";
    }
}

5
2017-08-13 13:48





指定编码的ony方法是在文件开头的XML声明中:

<?xml version="1.0" encoding="ISO-8859-1"?>

2
2017-11-26 13:43



这是唯一正确的答案 - 另见 stackoverflow.com/questions/8218230/... - iquito