深入分析AS3 TypeError: Error #1088: The markup in the document following the root element must be well-formed异常

在AS3里解析XML时遇到一“诡异”异常:TypeError: Error #1088: The markup in the document following the root element must be well-formed.

Air工程,SDK4.5,代码如下:

var f:File = new File("e:/demo.xml");
var fs:FileStream = new FileStream();
fs.open(f, FileMode.READ);
var xml:XML;
xml = XML(fs.readMultiByte(fs.bytesAvailable, "UTF-8"));
//后面省略

demo.xml文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<root>
    <item>abc</item>
</root>

异常堆栈:

TypeError: Error #1088: The markup in the document following the root element must be well-formed.
at XMLParse()[E:\Projects\XMLParse\src\XMLParse.as:15]
at runtime::ContentPlayer/loadInitialContent()
at runtime::ContentPlayer/playRawContent()
at runtime::ContentPlayer/playContent()
at runtime::AppRunner/run()
at ADLAppEntry/run()
at global/runtime::ADLEntry()

这段逻辑在之前执行过N次未出过问题,现在诡异了- -

开始解决

在网上搜了一下有网友说将第5,6行的XML类型改为XMLList,如下:

var xml:XMLList;
xml = XMLList(fs.readMultiByte(fs.bytesAvailable, "UTF-8"));

的确不报异常了,断点跟踪到XMLList发现List长度为2

xml[0]:

<?xml version="1.0" encoding="utf-8"?>

xml1:

<root>
    <item>abc</item>
</root>

只需解析xml1的内容即可达到目的。

为什么之前解析无问题,而这次异常,我们可假设以前我解析XMLList时只有一项且内容为整个XML文件,下文来测试。

莫非是编码问题?

用Notepad2打开文件,查看编码为“UTF-8 包含签名”
xml-encode1.png

Notepad2查看编码
还有一项UTF-8,UTF-8包含签名 与 UTF-8区别在哪?先说明一下:

UTF8签名(BOM编码)位于文件前3个字节(内容为:EFBBBF),是专门用来告诉软件:该文件是UTF8编码的。
在一般情况下,有无签名不会带来问题,因为编辑器或者其他软件可以按照文本的内容来推断出是否是UTF8。

utf8-bom-hex-view.png

UltraEdit以16进度查看BOM编码
上图为demo.xml用UltraEdit以16进制查看的结果,前3字节BOM编码为EF BB BF

ok,将demo.xml编码转为“UTF-8”试试,异常不再,XMLList长度为1

list[0] :

<root>
    <item>abc</item>
</root>

之所以这段代码以前多次执行正常,是因为以前文件编码为“UTF-8”,上文的假想有误xml内容不是整个文件。

var f:File = new File("e:/demo.xml");
var fs:FileStream = new FileStream();
fs.open(f, FileMode.READ);
var xml:XML;
xml = XML(fs.readMultiByte(fs.bytesAvailable, "UTF-8"));    //异常解决
var list:XMLList;
list = XMLList(fs.readMultiByte(fs.bytesAvailable, "UTF-8"));
trace(list.length());   //长度为1
//后面省略

现在我们可猜测以上现象原因:

如果xml文件有BOM编码信息(UTF-8包含签名),AS3读取文件时通过BOM信息知道文件编码为UTF-8,不去处理“”行而直接将其当作XML内容。取得的XMLList会包含这行与节点内容。

如果xml文件无BOM编码信息(UTF-8),AS3将通过“”信息判定文件编码格式,这一段将作为信息标识而非文件内容进行处理。取得的XMLList只有节点一项内容。

写在最后

通过以上分析总结此异常处理方案有2(- -):

  1. XML转换改为XMLList转换,再取XMLList项进行解析。

  2. 去掉xml文件BOM信息,即改为“UTF-8”(不包含签名)编码格式。

标签:flash, actionscript3, xml, air

添加新评论