【问题标题】:PHP DOMDocument::save() saves as ASCII instead of UTF-8PHP DOMDocument::save() 保存为 ASCII 而不是 UTF-8
【发布时间】:2016-04-04 00:04:15
【问题描述】:

我正在使用 DOMDocumentSimpleXMLElement 创建格式化的 XML 文件。虽然这一切正常,但生成的文件保存为 ASCII,而不是 UTF-8。我找不到关于如何改变它的答案。

XML 是这样创建的:

    $XMLNS = "http://www.sitemaps.org/schemas/sitemap/0.9";
    $rootNode = new \SimpleXMLElement("<?xml version='1.0' encoding='UTF-8'?><urlset></urlset>");
    $rootNode->addAttribute('xmlns', $XMLNS);

    $url = $rootNode->addChild('url');
    $url->addChild('loc', "Somewhere over the rainbow");

    //Turn it into an indented file needs a DOMDocument...
    $dom = dom_import_simplexml($rootNode)->ownerDocument;
    $dom->formatOutput = true;

    $path = "C:\\temp";

    // This saves an ASCII file
    $dom->save($path.'/sitemap.xml');

生成的 XML 看起来像这样(我认为应该是这样):

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>Somewhere over the rainbow</loc>
  </url>
</urlset>

不幸的是,该文件是 ASCII 编码而不是 UTF-8。

我该如何解决这个问题?

编辑:不要使用notepad++检查编码

感谢下面接受的答案,我现在可以使用它了。有一个注意事项:我使用 Notepad++ 打开文件并检查编码。但是,当我重新生成文件时,Notepad++ 会更新其选项卡并出于某种原因将 ANSI 指示为编码。在 Notepad++ 中关闭和重新打开同一个文件将再次指示 UTF-8。这让我很困惑。

【问题讨论】:

    标签: php xml utf-8 domdocument


    【解决方案1】:

    我认为这里发生了几件事。一方面,您需要:

    $dom->encoding = 'utf-8';
    

    而且,我认为我们应该尝试手动创建DOMDocument,并指定正确的编码。所以:

    <?php
    
    $XMLNS = "http://www.sitemaps.org/schemas/sitemap/0.9";
    $rootNode = new \SimpleXMLElement("<?xml version='1.0' encoding='UTF-8'?><urlset></urlset>");
    $rootNode->addAttribute('xmlns', $XMLNS);
    
    $url = $rootNode->addChild('url');
    $url->addChild('loc', "Somewhere over the rainbow");
    
    // Turn it into an indented file needs a DOMDocument...
    $domSxe = dom_import_simplexml($rootNode)->ownerDocument;
    
    // Set DOM encoding to UTF-8.
    $domSxe->encoding = 'UTF-8';
    
    $dom = new DOMDocument('1.0', 'UTF-8');
    $domSxe = $dom->importNode($domSxe, true);
    $domSxe = $dom->appendChild($domSxe);
    
    $path = "C:\\temp";
    
    $dom->formatOutput = true;
    $dom->save($path.'/sitemap.xml');
    

    还要确保您添加的任何元素或 CData 实际上是 UTF-8(请参阅 utf8_encode())。

    使用上面的示例,这对我有用:

    php > var_dump($utf8);
    string(11) "ᙀȾᎵ⁸"
    
    php > $XMLNS = "http://www.sitemaps.org/schemas/sitemap/0.9";
    php > $rootNode = new \SimpleXMLElement("<?xml version='1.0' encoding='UTF-8'?><urlset></urlset>");
    php > $rootNode->addAttribute('xmlns', $XMLNS);
    php > $url = $rootNode->addChild('url');
    
    php > $url->addChild('loc', "Somewhere over the rainbow $utf8");
    
    php > $domSxe = dom_import_simplexml($rootNode);
    php > $domSxe->encoding = 'UTF-8';
    php > $dom = new DOMDocument('1.0', 'UTF-8');
    php > $domSxe = $dom->importNode($domSxe, true);
    php > $domSxe = $dom->appendChild($domSxe);
    php > $dom->save('./sitemap.xml');
    
    
    $ cat ./sitemap.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><url><loc>Somewhere over the rainbow ᙀȾᎵ⁸</loc></url></urlset>
    

    【讨论】:

    • 您的代码将输出中的描述性 XML 元素更改为 &lt;?xml version="1.0" encoding="utf-8"?&gt;(请注意,utf-8 现在变为小写)但它不会更改仍被检测为的文件的实际编码ANSI。
    • 小写也可以。但是,您是否包括了$dom-&gt;encoding = 'utf-8';$dom-&gt;saveXML()?您确定要添加的元素是 UTF-8 格式吗?你能举一个更真实的例子,将一些 UTF-8 数据添加到 DOM 树中吗?
    • 我确实包含了$dom-&gt;encoding = 'utf-8';,但我错过了saveXML()。 Tho saveXML() 给了我一个错误:Error Type: 4096 Message: Argument 1 passed to DOMDocument::saveXML() must be an instance of DOMNode, string given(这是意料之中的,因为 saveXML() 根据文档将 XML 转储为字符串)编辑:让我举一些例子给你。
    • 好的,我更新了我的示例,尝试了不同的方法。这似乎适用于我的环境。但是,如果您可以展示一个将 UTF-8 字符串添加到文档中的示例,将会有所帮助。
    • 我让它运行你的代码!谢谢!还有其他原因,我使用 Notepad++ 来检查编码,但其中似乎有一个错误,当 Notepad++ 在检测到更改后自动更新文件时,它说编码是 ANSI。关闭文件并重新打开,它将再次指示 UTF-8。这花了我一些时间。
    【解决方案2】:

    您的数据不得采用 UTF-8 格式。你可以像这样转换它:

    utf8_encode($yourData);
    

    或者,也许:

    iconv('ISO-8859-1', 'UTF-8', $yourData)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-26
      • 2017-01-02
      • 2011-12-13
      • 2016-07-23
      • 1970-01-01
      • 2012-08-04
      • 1970-01-01
      • 2016-09-29
      相关资源
      最近更新 更多