欧元货币符号中断 XML 文件

Euro Currency Symbol breaks XML document

我正在使用 PHP File_Put_Contents 向 XML 文档添加内容,然后我正在使用 Microsoft Word 打开该文档。问题是,如果我添加欧元货币符号 (),那么文档就会中断,我会收到以下错误:

您尝试过使用“€”吗?并确保使用下面的片段清理字符串:

$currentString = preg_replace("[^!-~ ]", '', $currentString);

€ 不是有效的 XML 实体。

尝试解决实体的编码问题是一种糟糕的做法。相反,请确保所有字符串都是正确的 UTF-8。

首先确保您的字符串实际上是 UTF-8。 PHP 中的方法和函数期望它是独立于输出的 UTF-8。可以使用其他字符 sets/encodings 但这真的很复杂。

如果您使用 XML API(例如 DOM 或 XMLWriter 创建 XML,它将根据需要处理编码。在 UTF-8 XML 文档中, 不需要编码。

$document = new DOMDocument('1.0', 'UTF-8');
$document
  ->appendChild($document->createElement('price'))
  ->appendChild($document->createTextNode('€ 42.00'));

echo $document->saveXml();

输出:

<?xml version="1.0" encoding="UTF-8"?>
<price>€ 42.00</price>

但是在 ASCII XML 文档中,特殊字符需要编码为数字实体。 &euro; 之类的命名实体将不起作用。它们特定于 (X)HTML 而不是 XML。

$document = new DOMDocument('1.0', 'ASCII');
$document
  ->appendChild($document->createElement('price'))
  ->appendChild($document->createTextNode('€ 42.00'));

echo $document->saveXml();

输出:

<?xml version="1.0" encoding="ASCII"?>
<price>&#8364; 42.00</price>

XMLWriter:

也可以这样做
$writer = new XMLWriter();
$writer->openMemory();
$writer->startDocument('1.0', 'ASCII');
$writer->writeElement("price", '€ 42.00');
$writer->endDocument();
echo $writer->outputMemory();

如果您将 XML 生成为文本(通常不是最佳选择),您将不得不自己处理编码:

echo '<?xml version="1.0" encoding="UTF-8"?>', "\n";
printf('<price>%s</price>', htmlentities('€ 42.00', ENT_XML1 | ENT_COMPAT, "UTF-8"));

输出:

<?xml version="1.0" encoding="UTF-8"?>
<price>€ 42.00</price>