分享
 
 
 

选择和识别 XML 字符编码的方式

王朝other·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

在存储、传输或处理文本时,有必要了解字符编码方式。这种规则也适用于 xml,因为 XML 是基于文本的。

尽管可以使用多种方法对 XML 进行编码,却并没有关于使用哪种编码方式以及如何进行识别的准则。因此,本技术说明阐述了将字符编码方式应用到 XML 的最佳应用。

选择 XML 实体的字符编码方式

在选择所使用的字符编码方式时,必须首先了解可以选择哪些方式。在涉及到标准规范和执行环境的那些特定 XML 应用程序的情况下,可能将编码方式限定在某个范围内。实际上,在一种特定情况下,可能只有一种选择。

术语“规定编码方式”是指在这种情况下必须使用的编码方式。例如,编程环境的字符串数据类型可能必须包含在预定的编码方式中,如 java 字符中的 UTF-16 或 SQL 字符数据类型中的数据库字符集。唯一的编码方式经常以不同的方法进行规定。表 1 显示了这类情况的一些其他示例。

表 1. 规定唯一编码方式的示例

注重:Oracle XDK for C/C++ 提供一种非凡的模式,答应以任意的单字节字符编码方式来创建 DOM 树,而 API 以指定编码方式工作。此特性用于优化目的,被看作是例外情况,因为其目的是用于那些已了解数据包含指定字符集中字符的情况。强烈建议您始终使用 xmlinitenc 初始化函数或将 data_encoding 属性指定给 XML 上下文。

使用规定编码方式是一种最佳应用,因为您不必关注文档内或文档本身的编码信息 — 用户始终了解编码方式。因此减少了出错机率并可以提高效率。

但是即使规定了编码方式,XML 处理器也可能不“了解”它 — 在这种情况下,应用程序必须确保使用规定的编码方式。例如,假如 Java 应用程序有一个 DOM 树必须串行化为 UTF-8 [RFC-3629] 格式的输出流,则在将输出从 Writer 转换到 OutputStream 时,通过明确指定 UTF-8 可以确保该过程的执行。以下伪代码是在 Java Servlet 中指定输出编码方式的一个示例:

/* response is an http servlet response object */

response.setCharacterEncoding("UTF-8"); // set the output encoding to UTF-8

PRintWriterw = response.getWriter(); // get the output stream mandated to UTF-8

:

/* doc is an instance of an XML */

doc.print(w); // the document printed in the specified encoding

同样,假如您的输入必须是 UTF-8 格式,则您的应用程序应该编写为只接受 UTF-8 格式的输入。例如,在 Java 语言中,您可能需要使用构造符创建 InputSource 对象,该构造符使用一个参数来指定输入编码方式。此外,您可以从输入流中创建 InputStreamReader,指定 UTF-8 作为输入编码方式。以下伪代码说明如何在 Java 语言中指定输入编码方式。

InputSourceis = new InputSource();// create an input source

is.setByteStream(request.getInputStream()); // set the input stream mandated to UTF-8

is.setEncoding("UTF-8");// set the mandate encoding to the input source

parser.parse(is); // the parser will parse in the specified encoding

常用编程环境的大部分字符串数据类型都将字符编码方式限定在特定的范围中。即使提供多种选择,通常也会有某些约束。例如,标准库和 Oracle 库必须支持用于 C/C++ 中 char 类型的字符编码方式。使用 FORCE_INCODING 标志或 input_encoding 属性来指定规定的或外部指定的输入编码方式。以下伪代码演示了如何为 C 的 XDK 指定规定编码方式。

// parse an input stream in UTF-8 with DOM

XmlLoadDom(ctx, &err, "stream", in, "input_encoding", "UTF-8", NULL);

// parse an input stream in UTF-8 with SAX

XmlLoadSax(ctx, &err, "stream", in, "input_encoding", "UTF-8", NULL);

// print the document in UTF-8

XmlSaveDom(ctx, &err, doc, "stream", out, "output_encoding", "UTF-8", NULL);

选择规定字符编码方式

假如应用程序不需要支持多种编码方式,它可以为其本身规定唯一的编码方式。

假如规定了一种编码方式,则这种方式应该是 UTF-8 或 UTF-16 [RFC-2781] — 否则交互操作性将受到严重影响,因为使用文档的 XML 处理器可以不支持其他编码方式。假如需要与 US-ASCII [RFC-20] 兼容,或者需要以串行化格式进行传输或存储,则建议使用 UTF-8。在其他情况下,可能适于使用 UTF-16。

支持多种编码方式

需要支持多种编码方式的应用程序能够支持 XML 处理器所支持的任何编码方式。所有的 XML 处理器都支持 UTF-8 和 UTF-16。它们通常也支持一些常用的本地编码方式。

虽然 Oracle XML 处理器支持所有常用编码方式以及许多其他编码方式,但建议仅在必要时答应多种编码方式。应用程序不应该包含那些不使用 UTF-8 或 UTF-16 编码方式的 XML 文档,除非知道用户支持该编码方式并且其内容可以使用编码方式表达。例如,假如数据库字符集不是 Unicode,则不赞成在数据库中包含 XML 文档并在数据库字符集中利用它为未知用户提供服务。

为接收各种编码方式的输入实体,应该由 XML 处理器以字节流的形式不加更改地读取输入流。确保将外部提供的编码信息(例如内容类型的 HTTP 标题中的 charset 参数)传递到 XML 处理器,以便在 XML 处理器分析输入时强制为指定的编码方式。这种情况就象指定的编码方式就是规定编码方式一样。

为了以任意编码方式生成输出,需要确保实体带有字符编码信息,其方法是通过外部标记实现,如 HTTP 标题的 charset 参数以及 Oracle Files 或 Oracle XML DB 等信息库中的字符集属性,或者是通过嵌入标记实现(即编码声明)。

外部标记优先于内部标记,因为外部标记更可靠并更易于处理;尽可能不使用内部标记是明智的选择。实际上,先前曾讨论过,因为通常不了解编码方式,所以一般不需要内部标记。

经常由于所需的字符集转换而使声明的编码方式与实际编码方式不一致。例如,假如您将带有编码声明信息的文档插入 CLOB 类型的数据库列中,或通过 Java 字符流来读取它时,其声明不会神奇地转变为实际的值。通过使用 NLS_LANG 设置和 Java 字符数据类型等更高级协议来维护正确的编码方式时,很轻易避免这种情况。(Oracle 的 XMLType 数据类型可满足处理多种字符编码方式的预期情况。)

外部与内部编码信息的对比

字符编码信息的来源可以分为两类:外部或内部。本章讨论二者之间的重要差别。

外部编码信息

图 1 描述了分析器如何根据一种外部编码信息源 — HTTP 的内容类型标题 — 确定字符编码方式。注重,这里没有使用内部编码信息。

当输入是以 HTTP 或者任何可以从外部识别其编码方式的其他形式传入时,应用程序应该完成以下工作中的一项:

将 charset 参数的值传递给分析器

根据 charset 参数将输入流转换为 Unicode

指示分析器来分析 URI

使用复合编码方式需要的数据类型

内部编码信息

图 2 显示了分析器如何通过自动检测来确定字符编码方式。注重,文档必须具有正确的字节顺序标记 (BOM) 和/或编码声明。

在没有提供外部编码信息的情况下,可以使用自动检测。例如:

XML 作为文件存储在文件系统中。

发送方没有提供外部编码信息,并且没有规定编码方式。

内部字符编码信息来源的具体信息

我们已经讨论了将会使用何种编码方式以及如何在运行时指定、传输和确定这种方式,就让我们来探讨字节顺序标记和编码声明,这些是自动检测字符编码方式的工具。

字节顺序标记 (BOM)

BOM(Unicode 字符 U+FEFF、ZERO WIDTH NO-BREAK SPACE)可以出现在 XML 实体的开始部分。在 XML 中,BOM 不仅用于显示输入文本流的字节顺序,而且可以帮助检测字符编码方式。XML 处理器通常检查输入流的前几个字节,以判定编码方式是否为 UTF-16 或 ASCII,因此 XML 处理器能够读取可能在 XML 标题中提供的编码声明。UTF-16 格式的实体需要具有供自动检测使用的 BOM,因为 UTF-16 编码方式具有两种形式:UTF-16BE(big endian:fe ff)和 UTF-16LE(little endian:ff fe)。虽然没有字节顺序问题,但 UTF-8 格式的实体可以具有 BOM (ef bb bf)。BOM 不是文档的一部分,因此不能从用户代码中读取。通常 XML 处理器在必要时添加或删除 BOM。

编码声明

编码声明是 XML 标题的参数之一(非凡称为 XML 或文本声明)。例如

引入编码声明是为了在缺少外部字符编码信息的情况下进行分析时,为那些不使用 UTF-8 或 UTF-16 编码方式的实体提供字符编码信息。一种常见的误解认为,假如 XML 实体正在使用的不是 UTF-8 或 UTF-16 的编码方式,则它必须具有编码声明。实际上,假如知道编码方式,则编码声明没有用处,这经常是问题之所在。XML 分析器提供了一种指定每个输入实体字符编码方式的方法。假如分析器知道实体的编码方式,则声明中的值并不重要。假如以传递给分析器的参数形式从外部提供了编码信息,则通常忽略该值。在其他情况

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有