本文阐述了 Apusic 对 XML 文件处理的详细分析,及其现有情况下 Apusic 对 XML 文件解析存在的问题。
Apusic 服务器对于 XML 文件解析应该分为两种情况:一种 Apusic 需要加载的 XML 文件。如 :Apusic 的配置文件, J2EE 应用的 web.xml,application.xml 文件等。另外一种是用户代码中使用 DocumentBuilderFactory , SAXParserFactory 来解析自己的 XML 文件。对于上面两种情况的 XML 文件, Apusic 是予以不同处理的。以下对此做具体说明。
对于这一块的解析,我们现在是采用自己的 XML 解析器来实现的,我们自己的 XML 解析器就是 com.apusic.xml.parsers , com.apusic.xml.reader 下的相关类来处理的,和朱华明讨论过,我们对于上述文件采用自己的解析器处理是存在优势的。因为我们对这些文件的结构很了解。效率应该会高于任何第三方的 XML 解析器。但是我们的解析器可能也会存在一些不足的地方,对于一些复杂的 XML 结构的处理可能会存在问题。由于考虑到效率问题,所以这一块应该不需要使用第三方的 XML 解析器,还是使用我们自己的解析器为好。
用户应用程序使用 DocumentBuilderFactory, SAXParserFactory 对自己的 XML 解析时,由于我们在 Apusic.jar 中,对 META-INF/service/ 文件夹下设置了 javax.xml.parsers.DocumentBuilderFactory , javax.xml.parsers.SAXParserFactory 两个属性的值,并指向了 Xerces, 所以用户在解析 XML 时,缺省情况下使用的就是 Xerces API 进行操作的。因此这一块应该是不会存在问题。
至于设置此属性后是如何利用 Xerces API 进行解析 XML 的原理,当你阅读了 Java 相关源代码后就可以明白。具体可以阅读 javax.xml.parsers 包下的 DocumentBuilderFactory.class,SAXParserFactory.class 类的 newInstance 方法。
现在我们会遇到修改 Apusic 配置文件后, Apusic 无法启动的情况。这种情况主要是因为我们使用了自己的 XML 解析器。而我们的解析器在处理 UTF-8 编码文件时存在问题,因为文本文件在文件的头部存在 BOM (Byte Order Mark) 标识 , 而这个 BOM 标识是用来表示文件的字节顺序。对于不同编码格式的文件存在不同的 BOM 标识 , 文件的 BOM 标识规范可以参考下表(表 1 ),由于 UTF-8 文件不存在字节顺序的问题,所以这个文件 BOM 标识在 UTF-8 编码方式下是可有可无的。而当我们修改配置文件并保存后,如果存在 BOM 标识,我们的解析器就会出错,不存在 BOM 标识时,我们的解析器就能够正确工作。所以我们需要在解析 UTF-8 的时候,判断头部是否包含 UTF-8 的 BOM 标识,如果有就需要跳过去。代码修改主要是在 XmlReader.java 文件中做如下处理:
//skip UTF-8 BOM (byte order mark) if (count >= 3 && pos == 0){ if (buffer[0] == (byte)0xEF && buffer[1] == (byte)0xBB && buffer[2] == (byte)0xBF){ pos += 3; } } |
<!----> <o:p> </o:p>
UTF-8 |
EF BB BF |
UTF-16 Big Endian |
FE FF |
UTF-16 Little Endian |
FF FE |
UTF-32 Big Endian |
00 00 FE FF |
UTF-32 Little Endian |
FF FE 00 00 |
<o:p> </o:p>
( 表 1)
<o:p> </o:p>
为什么我们对 UTF-16,UTF-32 等编码方式文件存在 BOM 标识时没有问题呢?其实这个问题应该是 Java 的一个 bug , Java 的文本流在处理其他编码方式的时候能够很好的处理这个 BOM 标识,但是对于 UTF-8 编码时不能够正确处理。该 bug 可以参考以下地址:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
<o:p> </o:p>