使用 writeAttribute() 方法使用 XMLWriter 进行 php XML 导出问题

2023-12-03

我正在将表数据导出到 xml 中,其中在内容列中包含多语言内容并混合了 html,例如

$xmlWriter->writeAttribute('value', $contents);

record:

name="testing" , contents="Just <span style="color:red">testing</span>:漢字"

导出为:

<entry key="testing" value="Just &lt;span style='color:red'&gt;testing&lt;/span&gt;:&#x6F22;&#x5B57;">

预期的:

<entry key="testing" value="Just &lt;span style='color:red'&gt;testing&lt;/span&gt;:漢字">

我不希望 xml writer 对多语言字符进行编码,这怎么可能?


我不希望 xml writer 对多语言字符进行编码,这怎么可能?

实际上,当您编写 XML 时,您就已经进行了编码。您的意思是您不想对这两个字符使用数字实体,这是可能的,但并非总是如此。

要不使用数字实体,您需要将文档的编码与字符串的编码相匹配。从您提供的输出中我只能猜测一点,这两个字符可能代表:

  1. Unicode 汉字 '中国人民,汉语' (U+6F22)
  2. Unicode 汉字 '字母、字符、单词' (U+5B57)

这可能意味着(到目前为止我不会说任何中文)中文字.

PHP 中的 XMLWriter 总是将字符放入数字实体中(例如&#x6F22; and &#x5B57;在您的示例中)每当文档的编码无法表示文档中的该字符时。

如果您能够匹配两种编码,XMLWriter 将自动不使用数字实体。

我举一个更简单的例子。让我们以US-ASCII编码和德语变音Ä from Äpfel (符号库 > Unicode字符库 > Unicode区段:拉丁语大写字母 A 与分音符号 > (U+00C4)) 作为属性值:

<?php
$xmlWriter = new XMLWriter();
$xmlWriter->openMemory();
$xmlWriter->startDocument('1.0', 'US-ASCII');
$xmlWriter->startElement('root');
$xmlWriter->writeAttribute('value', 'Äpfel');
$xmlWriter->endDocument();
echo $xmlWriter->flush();

在 UTF-8 编码的 PHP 文件中编写的这段代码在执行时将输出:

<?xml version="1.0" encoding="US-ASCII"?>
<root value="&#196;pfel"/>

&#196;是 unicode 字符 U+00C4 的数字实体,如果仔细观察,C4 是十进制 196 的十六进制表示形式,这也表明数字 XML 实体始终表示 Unicode 字符编号。

因此 XML 输出使用 US-ASCII 编码,该编码无法表示Ä来自 PHP 代码中的 UTF-8 编码字符串,因此使用其数字实体对其进行正确编码以保留字符信息。

现在更改编码:

$xmlWriter->startDocument('1.0', 'US-ASCII');

PHP 字符串的 UTF-8 编码:

$xmlWriter->startDocument('1.0', 'UTF-8');

确实改变了这个输出:

<?xml version="1.0" encoding="UTF-8"?>
<root value="Äpfel"/>

这同样适用于您的示例,但是,您的问题中缺少一个重要信息:该记录中的字符串采用哪种编码?

如果它已经是 UTF-8,那么就像我在上面的示例中概述的那样,它已经可以工作了:

<?php
$recordUTf8 = "... contents=\"Just <span style=\"color:red\">testing</span>:"
             ."\xE6\xBC\xA2\xE5\xAD\x97\"";
$encoding   = 'UTF-8';
$encoding   = 'US-ASCII';

$xmlWriter = new XMLWriter();
$xmlWriter->openMemory();
$xmlWriter->startDocument('1.0', $encoding);
$xmlWriter->startElement('record');
$xmlWriter->writeAttribute('value', $recordUTf8);
$xmlWriter->endDocument();
echo $xmlWriter->flush();

Output:

<?xml version="1.0" encoding="UTF-8"?>
<record value="... contents=&quot;Just &lt;span style=&quot;color:red&quot;&gt;
               testing &lt;/span&gt;:漢字 &quot;"/>

正如此输出所示,此处没有使用数字实体,但是,该字符串显然是 UTF-8 编码的(此处以二进制安全方式进行编码,以防在复制 PHP 文件时对 PHP 文件使用不同的编码)。

总结一下:XML 编码需要与字符串的编码相匹配,以表示所有不在数字实体中的字符(除了用于对 XML 本身进行编码的字符之外,例如<, >, ', " and &).

这些几乎都是 XML 基础知识。如果文档具有无法表示字符数据的编码,但由于 XML 支持 Unicode,则后备是数字实体。您试图通过将文档编码与字符串编码对齐来防止这种回退。

这是我对 PHP 和 XMLWriter 的具体建议:

  1. 从数据库中获取记录或将记录重新编码为 UTF-8。
  2. 仅将 UTF-8 字符串传递给XMLWriter方法。
  3. 将 XML 文档编码设置为 UTF-8。

我给出这些建议是因为 UTF-8 是 XML 的默认编码,并且 PHP 中对 UTF-8 的支持相当好。此外,XMLWriter 期望 Unicode 字符串采用 UTF-8 编码,没有任何设置或选项允许您更改它,因此输入已经需要采用 UTF-8 编码。

无论输入字符串如何独立,您自然可以告诉 XMLWriter 使用不同的输出编码。例如,任何其他中文或 Unicode 编码可能适合您,并且只要您的 PHP 配置支持该特定输出编码(检查 iconv 库你有)。

当您使用 XMLWriter 启动文档时,第二个参数指定编码:

$xmlWriter->startDocument('1.0', $encoding);

您可以在相应的 XML 声明中放入 XML 支持的编码集中的任何编码:

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

XML 编码值的完整规范可以在这里找到:http://www.w3.org/TR/REC-xml/#NT-EncName ::

在编码声明中,值“UTF-8 ", " UTF-16 ", " ISO-10646-UCS-2“, 和 ”ISO-10646-UCS-4“应该用于 Unicode / ISO/IEC 10646 的各种编码和转换,值”ISO-8859-1 ", " ISO-8859-2“,……”ISO-8859-n "(其中 n 是零件编号)应用于 ISO 8859 的零件,并且值 "ISO-2022-JP ", " Shift_JIS“, 和 ”EUC-JP" 应用于 JIS X-0208-1997 的各种编码形式。建议使用互联网号码分配机构 [IANA-CHARSETS] 注册的字符编码(作为字符集),除了刚才列出的那些之外,还可以使用它们的注册名称;其他编码应使用以“x-”前缀开头的名称。XML 处理器应以不区分大小写的方式匹配字符编码名称,并且应将 IANA 注册名称解释为在 IANA 注册的该名称的编码,或者将其视为未知(当然,处理器不需要支持所有 IANA 注册的编码)。

[IANA-CHARSETS] 是:

(互联网号码分配机构)字符集的正式名称,编辑。凯尔德·西蒙森等人。 (看http://www.iana.org/assignments/character-sets.)

这些规格可能有点冗长。在您的问题中,您所需要做的就是找出记录字符串的编码。顺便说一句。不能说我无法重现你的exact输出,我总是得到十进制实体,而不是十六进制实体。您也许可以通过以下方式提供更多信息字符串的十六进制转储.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 writeAttribute() 方法使用 XMLWriter 进行 php XML 导出问题 的相关文章

  • 如何使用 Google 帐户对我们网站中的用户进行身份验证

    如何在我们的网站中使用 Google 帐户对用户进行身份验证 我希望用户重定向到谷歌登录页面 然后将他重定向到我的网站 我想要这个 PHP 实现 你要OAuth http code google com apis accounts docs
  • 如何将粘在一起的单词分开?

    我有很多命名不好的文件 videoofmegoingtoschool avi 是否有一个库或某种算法可以正确地将其分离 video of me going to school avi 我不认为那里有什么 我可以想象一个程序 它使用单词词典并
  • 如何在 WordPress 中按类别获取所有帖子

    我想在 WordPress 中按类别获取帖子 args array post type gt project postslist get posts args 0 gt WP Post 对象 ID gt 421 post author gt
  • PHP 基本身份验证 file_get_contents() [重复]

    这个问题在这里已经有答案了 我需要从网站解析一些 XML 数据 XML 数据是原始格式 但在我需要进行身份验证之前 基于基本网络服务器的身份验证 使用用户名和密码 I tried homepage file get contents htt
  • 在 JAVA 中使用 SAX 解析器从 XML 文件中提取文本节点

    因此 我目前正在使用 SAX 尝试从我正在处理的大量 xml 文档中提取一些信息 到目前为止 提取属性值确实很容易 但是 我不知道如何从文本节点中提取实际值 例如 在给定的 XML 文档中
  • PHP使用auto_increment生成短唯一ID?

    我想生成一个简短的 唯一的 ID 而不必检查冲突 我目前正在做类似的事情 但是我当前生成的 ID 是随机的 并且在循环中检查冲突很烦人 并且如果记录数量显着增加 将会变得昂贵 通常担心冲突不是问题 但我想要生成的唯一 ID 是一个由 5 8
  • Doctrine 1 和 Symfony 1 的多个主键?

    我已经知道在 Symfony 1 和 Doctrine 1 中不可能使用多个主键 但是你们知道有什么好的解决方法吗 除了多对多关系之外 原则 1 不适用于多列上的主键 但如果你想使用多对多关系 请像这样使用 BlogPost columns
  • 重新排列数组键 php [重复]

    这个问题在这里已经有答案了 我有这个数组 Array 15 gt 13 1 16 gt Mark one answer 19 gt You see a car on the hard shoulder of a motorway with
  • 将 Xml 反序列化为对象时出错 - xmlns='' 不是预期的

    我在尝试反序列化某些 XML 时遇到了真正的麻烦 希望有人可以提供一些帮助 我读过很多类似的帖子 但我无法解决这个问题 我正在尝试反序列化 XML
  • 选取散列第 N 个元素的最快方法

    我有一个大哈希表 带有字符串索引的数组 并正在寻找一个函数quickly从中选取第一个 理想情况下也是第 N 个 元素 array shift and reset 对于我的需求来说太慢了 UPDATE 我也不是在寻找基于引用的解决方案 该函
  • Windows iis 7.0 上的 APC 不稳定

    我的 IIS 非常不稳定 因为它总是由于某种与 APC 相关的原因而重新启动 服务器的规格如下 Intel R Xeon CPU 3GHZ 3GHZ 2GB RAM 64bit APC 和服务器规格 3 1 7 dev PHP Versio
  • PHP 错误警告:参数 1 应该是引用

    我 熟悉 PHP 我的朋友的网站因错误而崩溃 Warning Parameter 1 to Some function name expected to be a reference value given in public html i
  • 使用 sed 更新 xml 属性(Windows + cygwin 和 Linux)?

    我需要使用 sed 命令对 xml 文件进行更新 但我在这方面遇到了麻烦 它需要在 Windows 使用 cygwin 和 Linux 上运行 XML 具有以下元素
  • PHP:在脚本完成之前获取输出

    我有一个名为 data php 的脚本 如下所示 do some stuff echo result do some other stuff eg database operations 我需要在另一个脚本中使用 data php 的输出
  • PHP 错误:“无法通过引用传递参数 2”

    我只是需要有关这个 PHP 错误的帮助 我不太明白 致命错误 无法在第 13 行 web stud openup inactivatesession php 中通过引用传递参数 2
  • 如何确保在 PHP 的“foreach”循环中重置该值?

    我正在写一个简单的 PHP 页面和一些foreach使用了循环 以下是脚本 arrs array a b c foreach arrs as arr if substr arr 0 1 b echo This is b End of fir
  • 接口中的构造方法

    接口中的构造方法不好吗 为什么人们认为有人想要实例化接口 我们想要做的是强制实现者实现构造函数 就像其他接口方法一样 接口就像一个合同 假设我有一个接口 Queue 并且我想确保实现者创建一个带有一个参数的构造函数 该构造函数创建一个单例队
  • 使用来自另一个数据库的选择查询更新 mysql 表

    我有两个数据库 我想用另一个数据库表中的值更新一个表 我正在使用以下查询 但它不起作用 UPDATE database1 table1 SET field2 database2 table1 field2 WHERE database1 t
  • XSL字符串多重替换功能

    如何让这个函数进行多重替换 经验 替换aaa with 111并替换bbb with 222 etc
  • 谷歌日历手表过期时间超过1个月怎么办?

    我将我的 CRM 系统与 Google 日历同步 为此 我要求push notifications从我的用户 Google 日历到我的系统 我已经成功创建了手表 并将过期时间设置为2030年 但是当我收到手表事件的响应时 它显示手表的过期时

随机推荐

  • 如何解决 Eclipse 中的 multidex 错误

    我正在开发一个应用程序 在该应用程序中我使用了太多的库 最近我将 mixpanel lib 添加到我的项目中 之后就构建成功了 但是当我尝试运行该应用程序时 出现错误 2015 11 06 15 04 54 Dex Loader 无法执行
  • 弱小的自己去哪儿了?

    我经常这样做 let when DispatchTime now 2 0 DispatchQueue main asyncAfter deadline when beep 在一个应用程序中我们经常这样做 tickle fresh msg i
  • 在父方法中访问子方法的静态属性

    假设我有以下代码 class Parent static string MyField ParentField public virtual string DoSomething return MyField class Child Par
  • 如何从csv文件中读取自定义格式的日期?

    我正在解析一个 csv 文件 其数据为 03 10 2016 18 00 00 2 6 当我阅读文件创建架构时 如下所示 StructType schema DataTypes createStructType Arrays asList
  • 如何在 rglplot3d 中绘制曲面

    所以我有这段代码可以产生精确的表面 f function x y z x 2 3 y 2 exp x 2 y 2 plot3d f col colorRampPalette c blue white xlab X ylab Y zlab Z
  • C# 将日期时间转换为特定格式

    我想将日期时间转换为指定格式 Wed Aug 01 2012 14 37 50 GMT 0530 India Standard Time 实际上我想在网页上使用 Jquery 显示计时器 所以我尝试了一些我知道的格式 并找到了一些来自htt
  • 稀疏向量之和:缺陷还是特征?

    我最近在 MATLAB R2022a 中偶然发现了以下行为 gt gt a sparse 1 2 1 a 1 2 1 gt gt b sparse 2 1 18 b 2 1 18 gt gt a b ans 2 1 18 1 2 1 2 2
  • 如何将额外意图传递给两项活动

    我有一个应用程序 在第一个活动中询问第二页上的人名 它在句子中显示该名称我想在第三个第四或第九个活动中使用该名称我如何正确声明它 公开 并调用它我何时何地需要它 这是我发送的代码 Main public class MainActivity
  • Android 中的线程处理长时间运行的进程

    好吧 这是我的问题 我想学习 AsyncTask Threading 和 Handler 来处理长时间运行的任务 我使用了 Android Cook Book 和 New Boston Android 教程 但我无法使其工作 我需要更改进度
  • 使用动态 ID 选择 Multiple SelectManyCheckBox 中的所有项目

    我想使用 JSF 顶部的 PrimeFaces 组件来选择某些复选框组中的所有复选框 我的代码是这样的
  • 获取 RecyclerView 中的可见项

    我需要知道哪些元素当前显示在我的 RecyclerView 中 没有相当于OnScrollListener onScroll ListView 上的方法 我尝试与View getGlobalVisibleRect 但是这个 hack 太丑陋
  • 以编程方式登录站点

    这可能听起来很愚蠢 但是我们可以通过传递用户凭据 用户 ID 和密码 以编程方式登录 Linkedin 等网站吗 我不是在谈论使用 OAuth 或其他机制 Edit 您可以使用脚本以这种方式登录许多站点 我通常更喜欢使用 Beautiful
  • UITextView - 设置字体不适用于 XCode 5 上的 iOS 6

    我正在为我的用户界面使用故事板 我之前使用的是 XCode 4 6 并在 iOS 6 上发布 此后我使用 XCode 5 更新到 iOS 7 并更新了 Storyboard 以与 XCode 5 很好地配合 但我有一个问题 UITextVi
  • 在 React 的 useEffect() 中获取数据返回“未定义”

    我正在尝试从数据库中获取数据 这是一个获取请求 只要我在异步函数中使用获取的数据 一切都可以正常工作 但除此之外 它只是返回 未定义 我究竟做错了什么 感谢您的帮助 const accountInfos setAccountInfos us
  • 创建一个新文件,文件名包含循环变量,python [重复]

    这个问题在这里已经有答案了 我想在循环上运行一个函数 并且想将输出存储在不同的文件中 以便文件名包含循环变量 这是一个例子 for i in xrange 10 f open file i dat w f write str func i
  • Chrome 和 CSS 属性选择器

    我有以下 HTML 代码 我想用 css 格式化无法更改的数据格式 来自 xml 我必须为具有不同属性值的元素赋予不同的样式 我想使用 CSS 属性选择器 body background color black s text decorat
  • 如何在 Grails 脚本中访问服务?

    关于 create script run script 的文档很少 所以我想知道是否可以在 grails 脚本中注入 使用域类 在普通的 Grails 类中 我可以注入如下服务 定义我的服务 但我不确定 grails 脚本中的位置 要在脚本
  • jQuery,如何在 .load() 之后重新绑定 html 元素

    我有一个 html 组件 单击按钮后将重新加载该组件 组件的某些元素绑定到单击和悬停处理程序 一切工作正常 直到 load 调用函数来重新加载组件 加载组件的元素未绑定到相应的处理程序 此时 我将 js 脚本放在组件的末尾 以便它绑定元素
  • Flask 中的一对一关系

    我正在尝试使用 SqlAlchemy 在 Flask 中创建一对一关系 我按照之前的post我创建了如下类 class Image db Model tablename image image id db Column db Integer
  • 使用 writeAttribute() 方法使用 XMLWriter 进行 php XML 导出问题

    我正在将表数据导出到 xml 中 其中在内容列中包含多语言内容并混合了 html 例如 xmlWriter gt writeAttribute value contents record name testing contents Just