如何指定 libxml2 的默认输出编码以防止属性中过度的实体转义?

How to specify the default output encoding for libxml2 to prevent overzealous entity-escaping in attributes?

看来这个问题又咬我了。前段时间我在 dba 上问过一些类似的问题,认为这只是一个 PostgreSQL 问题,但是现在它在 php 中困扰着我。但共同点是底层的libxml2库。

我的经验使我相信某些操作会将属性值中的所有非拉丁字符(并且仅在属性值中)转换为转义实体,即 &#xHEX;。看起来好像在属性内部,作者忘记了它应该默认为 UTF-8 并假定为 ASCII。可以通过一些操作来缓解这个问题(如下面的代码所示),但这并不总是可行的(比如在 PostgreSQL 的存储函数中)。

显示问题的代码

<?php
$xml = <<<'XML'
<?xml version='1.0' encoding='UTF-8'?>
<root><элемент атрибут="&quot;знач.&quot;">текст</элемент></root>
XML;
$r = new XMLReader();
$r->xml($xml);
do {
    $r->read();
} while ($r->nodeType != XMLReader::ELEMENT);
$r->read();
echo $r->readOuterXml(), "\n";
$n = $r->expand(new DomDocument());
echo $n->ownerDocument->saveXml($n), "\n";
$n = $r->expand(new DomDocument('1.0', 'UTF-8'));
echo $n->ownerDocument->saveXml($n), "\n";
?>

产出

<элемент атрибут="&quot;&#x437;&#x43D;&#x430;&#x447;.&quot;">текст</элемент>
<элемент атрибут="&quot;&#x437;&#x43D;&#x430;&#x447;.&quot;">текст</элемент>
<элемент атрибут="&quot;знач.&quot;">текст</элемент>

我要的结果是最后一个

因此问题: libxml2 中是否有任何设置或某些东西以某种方式全局设置默认输出编码,而不管输入甚至是省略的输入?

这是 libxml2 中的一个错误,我 just fixed

请注意,您仍然需要在 XML 声明中提供明确的 UTF-8 编码。