XML :org.xml.sax.SAXParseException: Content is not allowed in prolog

本文探讨了在处理XML文件过程中遇到的“Content is not allowed in prolog”异常的原因及解决办法,涉及转义字符处理不当、文件编码问题及BOM字节序标记的影响。

转载自:http://askcuix.appspot.com/2011/02/17/content-is-not-allowed-in-prolog.html

     最近在做一些批处理XML的项目,通过Spring Batch读取XML,然后将数据存入数据库。XML是客户方通过AS400的技术将数据读出并写入到文件的,我不了解AS400处理这类问题是不是很麻烦,每次XML需要做些变动的时候,客户总是表现的很为难,并且都是很久才能给到新的XML,还总是有这样那样的问题,甚至都不是一个有效的XML。这两天总算是改的差不多了,但遇到了好几次这样的exception: org.xml.sax.SAXParseException: Content is not allowed in prolog。以前也接触过不少XML,可是这种问题还真是没遇到过。

      检查XML发现有一些转义字符没有做处理,&没有写成&amp;,这是出现这种错误的一种可能性,在XML规范中,明确的说明&和<需要做转义,不能直接出现在XML文档中,否则就不是一个有效的XML。修正了这个问题,一个XML处理成功了。

      在执行另外一个XML文件时,又遇到了这个问题,将转义字符的问题修正后,依然存在该错误,经过google的帮助,发现应该是文件编码的问题。检查该文件,是UTF-8编码,应该没问题的,结果问题就出在这个文件用UltraEdit编辑过,UltraEdit等一些编辑器会在无BOM头的UTF-8文件中加入BOM信息,但是XML解析器不认BOM。查看该文件的二进制内容,会发现在文件头有EF BB BF,在对应的字符串显示中可以看到它是在<?xml version="1.0" encoding="UTF-8"?>前的一个乱码字符,问题就出在了这个字符上。我平时是用NotePad++,在状态栏的文件编码中可以看到这个文件是UTF-8编码,我在encoding菜单中选择UTF-8 without BOM,这时文件编码就变成了ANSI-UTF8,同时EF BB BF也消失了,再执行这个文件就正确了。这个encoding选项在高版本的UltraEdit中也有,但是旧版本中是没有的。

      BOM - byte order mark,就是字节序标记,UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式, 如果接受者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了,Windows就是使用BOM来标记文本文件的编码方式的。对于BOM我没有深究,有兴趣的话可以参考:http://www.unicode.org/faq/utf_bom.html#bom1

      对于这个错误,还有一种可能性,就是有标签使用了中文输入法,比如<?xml version="1.0" encoding="UTF-8"?>写成了<xml version="1.0" encoding="UTF-8">,注意这两个问号都用了中文输入法。

      这是我已发现的出现这种错误的三个可能性,出现这种错误后,应检查文件编码,除此以外应该就是一些字符输入错误的问题了,有问题的朋友可以从这两个方面着手。据说新版本的JDom解决了这个问题,看来并不是所有的解析器都不认BOM,有时间的话还是要研究研究。

<think>好的,我现在遇到了一个XML解析错误,提示是“Elementtype ‘foreach’must be declared”。用户需要我作为编程专家给出解决方案,包括代码和解释,然后提出相关问题。首先,我需要分析这个错误的原因。 XML解析错误通常发生在文档结构不符合规范时。这里的错误信息指出“foreach”元素类型未声明。这说明XML文档中使用了未在DTD或XMLSchema中定义的元素“foreach”。常见的情况可能是: 1. **拼写错误**:比如元素名是否正确,比如应该是“for-each”而不是“foreach”。 2. **命名空间问题**:可能忘记声明命名空间,导致解析器无法识别元素。3. **未包含必要的DTD或Schema**:如果文档引用了外部DTD或Schema,但其中没有声明该元素,就会报错。 比如,在MyBatis的动态SQL中,正确的元素是`<foreach>`,但需要正确的命名空间。或者,可能是在配置文件中未声明相应的DTD,导致解析器无法识别元素。 接下来,我需要给出解决方案。首先检查XML文档是否有正确的DOCTYPE声明。例如,MyBatis的配置文件应该有: ```xml<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> ``` 如果DOCTYPE正确,但问题仍然存在,可能需要检查元素是否正确拼写,或者是否存在嵌套错误。例如,在MyBatis中使用foreach时,应该确保它在`<select>`, `<update>`等标签内,并且正确使用属性如collection、item等。 示例代码部分,可以展示一个正确的MyBatis mapper文件中的foreach用法,并解释各个部分的作用。然后,解释错误原因,比如缺少DTD声明或元素拼写错误。 最后,提出相关问题,可能涉及XML解析错误的常见原因、MyBatis动态SQL的其他标签、如何声明DTD,以及XML Schema和DTD的区别等。</think>这个XML解析错误通常发生在以下两种情况中: 1. 使用了未声明的XML元素(如MyBatis的foreach标签) 2. 缺少必要的DTD声明 以下是解决方案和示例代码: ```xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.UserMapper"> <select id="selectUsers" resultType="User"> SELECT * FROM users WHERE id IN <foreach item="id" collection="ids" open="(" separator="," close=")"> #{id} </foreach> </select> </mapper> ``` 代码解释: 1. `<!DOCTYPE>` 声明指定了MyBatis的DTD,这是识别`<foreach>`等标签的关键 2. `<foreach>`标签必须位于`<select>`, `<update>`等SQL操作标签内部 3. 标签的三个必要属性: - collection:要遍历的集合属性名 - item:当前元素的变量名 - open/close:循环开始和结束时的包装字符 常见错误原因: 1. 缺少DOCTYPE声明或URL不正确 2. XML元素拼写错误(正确是`<foreach>`不是`<for-each>`) 3. 元素嵌套顺序错误(如将`<foreach>`放在`<sql>`标签外)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值