【问题标题】:How do I tell DOMDocument->load() what encoding I want it to use?我如何告诉 DOMDocument->load() 我希望它使用什么编码?
【发布时间】:2010-11-19 03:53:01
【问题描述】:

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

你瞧,这些 XML 文件中没有指定编码。如果我 将 'encoding="iso-8859-1"' 添加到标题中,它工作正常。摩擦是 我无法控制这些 XML 文件。

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

【问题讨论】:

    标签: php xml dom domdocument


    【解决方案1】:

    这对你有用吗?

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

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

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

    【讨论】:

    • 试过这个 - 它似乎不会影响加载的文档 - 从我的阅读来看,我很确定编码会被 load() 调用重置
    【解决方案2】:

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

    <?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() 抑制),并且它还会显示在internal libxml errors 中(仅在解析器从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";
        }
    }
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      猜你喜欢
      • 2014-05-16
      • 2013-05-29
      • 1970-01-01
      • 2011-04-14
      • 2017-05-22
      • 1970-01-01
      • 1970-01-01
      • 2022-06-25
      • 2022-06-16
      相关资源
      最近更新 更多