SAX解析含特殊字符的xml文档(java)

12 篇文章 0 订阅

 

       

 

一、不含自定义字符或含较少量的特殊字符

 

一般的特殊字符有五个:&<,>,’(单引号),”(双引号)。这些字符如果直接出现在xml文档中,一般是不能解析出来的,如解析<example>a&b<example>时会报错。解决方法有两个:1.<![CDATA[ ]]>标记;2.转义。

 

1.  <![CDATA[ ]]>标记

 

对于含特殊字符的element<![CDATA[ ]]>标记起来即可成功解析,如<example><![CDATA[a&b]]><example>

 

该方法简单但不实用,对于每个含特殊字符的element都要用<![CDATA[ ]]>标记。数量很少是推荐用这种方法。

 

2.  转义

 

特殊字符数量很多时方法1显然不实用,此时可用转义来实现:

 

&lt; < 小于号

 

&gt; > 大于号

 

&amp; &

 

&apos; ' 单引号

 

&quot; " 双引号

 

即将xml中的特殊文档全部替换为转义字符,如<example>a&b<example>变成<example>a&amp;b<example>

 

但是对于这种情况解析过程会发生变化,不是一次性解析a&b,而是分三步,先解析a,然后是&,然后是b,因此要注意想要获得<example>中数据必须要用String变量将这三部分加起来。即解析程序中

 StringBuffer contentBuffer = new StringBuffer();

public void characters(char[] ch, int start, int length)

 

            throws SAXException {

 

        if(this.tagName!=null){

                                contentBuffer.append(ch, start, length);//当出现特殊字符时会循环调用当前方法,若想使字符串完整解析,使用StringBuffer更好一点,否则只使用String的话只会得到末尾的部分字符串。

            //String date=new String(ch,start,length);

 

            //date就是当前节点(tagName)解析出来的数据

 

            //example=example+date;

 

//example是已申明的用来存储<example>中数据的Sting变量

 

}

 

}

 

这样解析出的example变量才是a&b,如果直接用example=date;得到的example的变量的只是b

 

二、含自定义字符或含较多的特殊字符(用dtd文件验证)

 

DTD文件格式及验证xml原理(百度)

 

如何解析含DTDxml文件呢?

 

dtd文件导入当前工程,在xml文件中加入

 

<!DOCTYPE xml文件名 SYSTEM "src/dblp.dtd">即可。

 

如解析<example>a&uuml;b<example>,在dtd文件中声明

 

<!ENTITY uuml "&#252;"><!-- small u, dieresis or umlaut mark --> 验证&uuml;代表字符ü

 

三、含单引号的xml解析后插入数据库:

 

用上面方法可以解析出xml中含单引号的数据(String型数据),但要将数据插入数据库中却很容易出现问题,因为sql语句中不允许单独的单引号存在,解决办法很简单,将解析所得的数据中的单引号用函数replaceAll()替换成双引号在插入数据库即可。

 

四、解析含较多实体引用的大型的xml文档(如1G

 

xml实体引用都是以&开头,以;结尾,如第二大点中的&uuml;就是一个实体引用。对于大型的xml文档,含有的实体引用可能太多导致解析过程报错:Parser has reached the entity expansion limit "64,000" set by the Application.

 

即单个xml文件中实体引用超过了默认值64000个。这时只要在解析前设置单个xml文件中实体引用的最大数量即可,System.setProperty("entityExpansionLimit", "xxxxx");xxxxx代表设定的单文件实体引用数最大值。

 

Java 中使用 SAX 解析 XML 文档时,如果 XML 文档特殊字符,需要进行转义处理,否则会导致 SAX 解析错误。和 DOM 解析不同,SAX 解析器会在解析XML 文档中的每个元素和属性时,调用相应的回调方法,因此需要在处理回调方法中进行转义处理。 以下是 Java 中常见的 XML 特殊字符及其转义方式: - 小于符号 (<):使用 "<" 表示; - 大于符号 (>):使用 ">" 表示; - 双引号 ("):使用 """ 表示; - 单引号 ('):使用 "&apos;" 表示; - 和符号 (&):使用 "&" 表示。 以处理 XML 元素值为例,可以在 DefaultHandler 的 characters() 方法中进行转义处理,示例如下: ```java import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class MyHandler extends DefaultHandler { private StringBuilder currentElementValue; @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // 初始化当前元素值 currentElementValue = new StringBuilder(); } @Override public void characters(char[] ch, int start, int length) throws SAXException { // 将当前元素值加入 StringBuilder 中 currentElementValue.append(ch, start, length); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // 处理当前元素值中的特殊字符 String elementValue = currentElementValue.toString() .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll("\"", """) .replaceAll("'", "&apos;"); // 处理完特殊字符后,进行后续处理 // ... } } ``` 在上述示例中,使用 StringBuilder 来保存当前元素值,在 endElement() 方法中,先使用 toString() 方法将 StringBuilder 转化为字符串,然后使用 replaceAll() 方法将特殊字符转义为对应的实体。处理完特殊字符后,可以在 endElement() 方法中进行后续处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值