sax解析xml的特殊字符解决方法
2013-03-27 10:10
465 查看
1. 如果特殊字符很少,并且出现在特定的tag里,最简单的方法就是生成xml的时候加入标志“<![CDATA[formula]]>”如,
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<Root>
<ITEM>
<AreaID>1</AreaID>
<ParentID>0</ParentID>
<AreaName>0</AreaName>
</ITEM>
<ITEM>
<AreaID>2</AreaID>
<ParentID>1</ParentID>
<AreaName><![CDATA[aaa<bbb?1:2]]></AreaName>
</ITEM>
</Root>
2. 如果不确定哪一个tag会有像<,>等的特殊字符,或者出现特殊字符的tag比较多,则最好使用转义
因为SAX解析判断是否是一个element是通过<>,</>来判断的,所以想大于号、小于号等为了避免混淆,要使用转义
小于号 < <
大于号 > >
与号 & &
单引号 ‘ '
双引号 “ "
比如,
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<Root>
<ITEM>
<AreaID>1</AreaID>
<ParentID>0</ParentID>
<AreaName>0</AreaName>
</ITEM>
<ITEM>
<AreaID>2</AreaID>
<ParentID>1</ParentID>
<AreaName>a<b</AreaName>
</ITEM>
</Root>
package com.kingman.hello.xml;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.util.Log;
public class AreaHandler extends DefaultHandler{
private static final String TAG = "AreaHandler";
final int AREA_ID = 1;
final int PARENT_ID = 2;
final int AREA_NAME = 3;
AreaFeed mAreaFeed;
AreaItem mAreaItem;
private int currentstate;
private StringBuffer str = null;
public AreaHandler() {
}
@Override
public void startDocument() throws SAXException {
Log.v(TAG, "startDocument");
mAreaFeed = new AreaFeed();
mAreaItem = new AreaItem();
}
@Override
public void endDocument() throws SAXException {
Log.v(TAG, "endDocument");
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
Log.v(TAG, "startElement");
str = new StringBuffer();
if (localName.equals("ITEM"))
{
mAreaItem = new AreaItem();
return;
}
if (localName.equals("AreaID"))
{
currentstate = AREA_ID;
return;
}
if (localName.equals("ParentID"))
{
currentstate = PARENT_ID;
return;
}
if (localName.equals("AreaName"))
{
currentstate = AREA_NAME;
return;
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
Log.v(TAG, "endElement");
super.endElement(uri, localName, qName);
if (localName.equals("ITEM"))
{
mAreaFeed.addItem(mAreaItem);
return;
}
switch (currentstate)
{
case AREA_ID:
mAreaItem.setmAreaID(str.toString());
currentstate = 0;
break;
case PARENT_ID:
mAreaItem.setmParentID(str.toString());
currentstate = 0;
break;
case AREA_NAME:
Log.v(TAG, "AREA_NAME - str = " + str);
mAreaItem.setmAreaName(str.toString());
currentstate = 0;
break;
default:
return;
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
String theString = new String(ch,start,length);
str.append(theString);
Log.v(TAG, "str = " + str);
}
public AreaFeed getFeed() {
return mAreaFeed;
}
}
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<Root>
<ITEM>
<AreaID>1</AreaID>
<ParentID>0</ParentID>
<AreaName>0</AreaName>
</ITEM>
<ITEM>
<AreaID>2</AreaID>
<ParentID>1</ParentID>
<AreaName><![CDATA[aaa<bbb?1:2]]></AreaName>
</ITEM>
</Root>
2. 如果不确定哪一个tag会有像<,>等的特殊字符,或者出现特殊字符的tag比较多,则最好使用转义
因为SAX解析判断是否是一个element是通过<>,</>来判断的,所以想大于号、小于号等为了避免混淆,要使用转义
小于号 < <
大于号 > >
与号 & &
单引号 ‘ '
双引号 “ "
比如,
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<Root>
<ITEM>
<AreaID>1</AreaID>
<ParentID>0</ParentID>
<AreaName>0</AreaName>
</ITEM>
<ITEM>
<AreaID>2</AreaID>
<ParentID>1</ParentID>
<AreaName>a<b</AreaName>
</ITEM>
</Root>
<AreaName>a<b</AreaName>解析的时候,sax解析AreaName的时候进入startElement进入一次,会进入characters至少3次(说至少的意思是有些tag中间会有空格或TAB,本例中只会调用3次),分别会返回”a“, "<", "b",把这三次拼接起来就是我们需要的字串,完整程序如下
package com.kingman.hello.xml;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.util.Log;
public class AreaHandler extends DefaultHandler{
private static final String TAG = "AreaHandler";
final int AREA_ID = 1;
final int PARENT_ID = 2;
final int AREA_NAME = 3;
AreaFeed mAreaFeed;
AreaItem mAreaItem;
private int currentstate;
private StringBuffer str = null;
public AreaHandler() {
}
@Override
public void startDocument() throws SAXException {
Log.v(TAG, "startDocument");
mAreaFeed = new AreaFeed();
mAreaItem = new AreaItem();
}
@Override
public void endDocument() throws SAXException {
Log.v(TAG, "endDocument");
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
Log.v(TAG, "startElement");
str = new StringBuffer();
if (localName.equals("ITEM"))
{
mAreaItem = new AreaItem();
return;
}
if (localName.equals("AreaID"))
{
currentstate = AREA_ID;
return;
}
if (localName.equals("ParentID"))
{
currentstate = PARENT_ID;
return;
}
if (localName.equals("AreaName"))
{
currentstate = AREA_NAME;
return;
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
Log.v(TAG, "endElement");
super.endElement(uri, localName, qName);
if (localName.equals("ITEM"))
{
mAreaFeed.addItem(mAreaItem);
return;
}
switch (currentstate)
{
case AREA_ID:
mAreaItem.setmAreaID(str.toString());
currentstate = 0;
break;
case PARENT_ID:
mAreaItem.setmParentID(str.toString());
currentstate = 0;
break;
case AREA_NAME:
Log.v(TAG, "AREA_NAME - str = " + str);
mAreaItem.setmAreaName(str.toString());
currentstate = 0;
break;
default:
return;
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
String theString = new String(ch,start,length);
str.append(theString);
Log.v(TAG, "str = " + str);
}
public AreaFeed getFeed() {
return mAreaFeed;
}
}
package com.kingman.hello.xml; import java.io.InputStream; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.widget.ListView; import android.widget.SimpleAdapter; import com.kingman.hello.R; public class SAXParseActivity extends Activity{ public final String TAG = "XMLParseActivity"; private AreaFeed feed = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.xml_listview); feed = getFeed(R.raw.area); showListView(); } private AreaFeed getFeed(int r_id) { try { InputStream inputStream = null; //xml file 放到 assets目录中的 inputStream = getResources().getAssets().open("blog.xml"); //inputStream = openFileInput("blog.xml"); //创建SAX解析工厂 SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); XMLReader xmlreader = parser.getXMLReader(); //为XMLReader设置内容处理器 AreaHandler xmlHandler = new AreaHandler(); xmlreader.setContentHandler(xmlHandler); //设置事件处理函数 InputSource is = new InputSource(inputStream); //开始解析文件 xmlreader.parse(is); return xmlHandler.getFeed(); } catch (Exception ee){ return null; } } private void showListView() { Log.v(TAG, "showListView"); ListView itemlist = (ListView) findViewById(R.id.itemlist); if (feed == null) { setTitle("Can't display"); return; } SimpleAdapter adapter = new SimpleAdapter(this, feed.getAllItemsForListView(), R.layout.xml_three_textview, new String[] { AreaItem.AREA_ID, AreaItem.PARENT_ID , AreaItem.AREA_NAME}, new int[] { R.id.tv1 , R.id.tv2, R.id.tv3}); itemlist.setAdapter(adapter); itemlist.setSelection(0); } }
相关文章推荐
- android用SAX解析xml文件时抛出org.apache.harmony.xml.ExpatParser$ParseException异常的解决方法
- XML 文件中出现 & ? ? 这类特殊字符的一种解决方法
- android下SAX解析大xml数据时只解析出一部分的解决方法
- XML 文件中出现 & ® ™ 这类特殊字符的一种解决方法(from blog.joycode.com/ghj)
- 关于使用dom4j生成xml时特殊字符处理的解决方法
- XML中特殊字符出现乱码的解决方法
- sax解析内容中含有xml特殊字符转义实体的解决方案
- “无法显示 XML 页 - 名称以无效字符开头。”&&“ XML解析错误:未组织好”的解决方法
- 含有特殊字符的JSON串解析方法
- QT XML文档的解析 QXmlStreamReader, DOM,SAX 三种解析方法 简单示例
- Java解析xml的主要解析器: SAX和DOM的选择(附上新方法--Pull解析)
- Spring如何加载XSD文件(org.xml.sax.SAXParseException: Failed to read schema document错误的解决方法)
- android下载xml解析 文件尾出现NUL 导致解析异常的解决方法
- XStream解析xml的特殊字符支持
- EasyPlayerPro-Win 解决xml配置文件中特殊字符读取异常
- xml的四种解析方法及源代码(SAX、DOM、JDOM、DOM4J)
- ANDROID STRINGS.XML的特殊字符_安卓STRING.XML添加空格或字符的方法
- c#中XML解析文件出错解决方法
- url 特殊字符 传递参数解决方法
- 两种解析XML文档的方法---DOM和SAX