package com.eoe.xmlresolve.utils;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.content.Context;
import android.util.Xml;
import com.eoe.xmlresolve.vo.River;
public class XMLUtils
{
public static final String RIVER = "river";
public static final String NAME = "name";
public static final String LENGTH = "length";
public static final String INTRODUCTION = "introduction";
/**
* DOM解析
**/
public static List<River> DOMParse(Context context, String fileName)
{
List<River> rivers = new ArrayList<River>();
DocumentBuilderFactory factory = null;
DocumentBuilder builder = null;
Document document = null;
InputStream inputStream = null;
// 首先找到xml文件
factory = DocumentBuilderFactory.newInstance();
try
{
// 找到xml,并加载文档
builder = factory.newDocumentBuilder();
inputStream = context.getResources().getAssets().open(fileName);
document = builder.parse(inputStream);
// 找到根Element
Element root = document.getDocumentElement();
NodeList nodes = root.getElementsByTagName(RIVER);
// 遍历根节点所有子节点,rivers 下所有river
River river = null;
for (int i = 0; i < nodes.getLength(); i++)
{
river = new River();
// 获取river元素节点
Element riverElement = (Element) (nodes.item(i));
// 获取river中name属性值
river.setName(riverElement.getAttribute(NAME));
river.setLength(Integer.parseInt(riverElement.getAttribute(LENGTH)));
// 获取river下introduction标签
Element introduction = (Element) riverElement.getElementsByTagName(INTRODUCTION).item(0);
river.setIntroduction(introduction.getFirstChild().getNodeValue());
rivers.add(river);
}
} catch (IOException e)
{
e.printStackTrace();
} catch (SAXException e)
{
e.printStackTrace();
} catch (ParserConfigurationException e)
{
e.printStackTrace();
} finally
{
try
{
inputStream.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
return rivers;
}
/**
* SAX解析
*
* @param context
* @param xmlPath
* @return
*/
public static List<River> SAXParse(Context context, String xmlPath)
{
List<River> rivers = null;
SAXParserFactory factory = SAXParserFactory.newInstance();
try
{
SAXParser parser = factory.newSAXParser();
// 获取事件源
XMLReader xmlReader = parser.getXMLReader();
// 设置处理器
MyDefaultHandler handler = new MyDefaultHandler();
xmlReader.setContentHandler(handler);
// 解析xml文档
xmlReader.parse(new InputSource(context.getAssets().open(xmlPath)));
rivers = handler.getRivers();
} catch (ParserConfigurationException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return rivers;
}
private static class MyDefaultHandler extends DefaultHandler
{
private String currentElementName = "";
public List<River> rivers = new ArrayList<River>();
River river = null;
/**
* characters (char ch[], int start, int length)当解析xml中遇到文本内容时会执行。
* ch这个数组中存放的是整个xml文件的字符串的数组形式
* start是当前解析的文本在整个xml字符串文件中的开始位置
* length是当前解析的文本内容的长度 由上面的介绍我们可以知道,我们可以通过new String(ch,start,length)方法来获取我们正解析的文本内容
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException
{
// 标签内容
String textContent = new String(ch, start, length);
if (currentElementName.equals(INTRODUCTION) && textContent != null && !textContent.trim().equals(""))
{
river.setIntroduction(textContent);
}
}
/**
* 开始解析xml时触发
*/
@Override
public void startDocument() throws SAXException
{
super.startDocument();
}
/**
* 解析到xml文档的末尾时触发
*/
@Override
public void endDocument() throws SAXException
{
super.endDocument();
}
/**
* 解析到元素的开始处触发 startElement (String uri, String localName, String qName,
* Attributes attributes)
* uri:Namespace值,当用户没有明确指定以及当命名空间没有被使用的时候,为null
* localName:element的名称,或者通俗点叫标签的名称。如<name>中的name就是localName
* qName:和localName的唯一其别是,当标签有namespace时,该值返回的数据为全限定名称。例如<chen:name>中,localName为name,qName为chen:name
* attributes:元素包含的属性对象。如果没有属性时,返回一个空的属性对象
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
currentElementName = localName;
// 子标签属性
if (localName.equals(RIVER))
{
river = new River();
river.setName(attributes.getValue(NAME));
river.setLength(Integer.parseInt(attributes.getValue(LENGTH)));
}
}
/**
* 解析到元素的末尾时触发
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException
{
if (localName.equals(RIVER))
{
rivers.add(river);
}
}
public List<River> getRivers()
{
return rivers;
}
}
/**
* PULL解析
*/
public static List<River> PULLParse(Context context, String xmlPath)
{
List<River> rivers = new ArrayList<River>();
River river = null;
InputStream inputStream = null;
// 获得XmlPullParser解析器
XmlPullParser xmlParser = Xml.newPullParser();
try
{
// 得到文件流,并设置编码方式
inputStream = context.getResources().getAssets().open(xmlPath);
xmlParser.setInput(inputStream, "utf-8");
// 获得解析到的事件类别,这里有开始文档,结束文档,开始标签,结束标签,文本等等事件。
int evtType = xmlParser.getEventType();
// 一直循环,直到文档结束
while (evtType != XmlPullParser.END_DOCUMENT)
{
switch (evtType)
{
case XmlPullParser.START_TAG:
String tag = xmlParser.getName();
// 如果是river标签开始,则说明需要实例化对象了
if (tag.equalsIgnoreCase(RIVER))
{
river = new River();
// 取出river标签中的一些属性值
river.setName(xmlParser.getAttributeValue(null, NAME));
river.setLength(Integer.parseInt(xmlParser.getAttributeValue(null, LENGTH)));
} else if (river != null)
{
// 如果遇到introduction标签,则读取它内容
if (tag.equalsIgnoreCase(INTRODUCTION))
{
river.setIntroduction(xmlParser.nextText());
}
}
break;
case XmlPullParser.END_TAG:
// 如果遇到river标签结束,则把river对象添加进集合中
if (xmlParser.getName().equalsIgnoreCase(RIVER) && river != null)
{
rivers.add(river);
river = null;
}
break;
default:
break;
}
// 如果xml没有结束,则导航到下一个river节点
evtType = xmlParser.next();
}
} catch (XmlPullParserException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
return rivers;
}
private InputStream readDataFromFile(Context context, String fileName)
{
//从本地获取数据
InputStream inputStream = null;
try {
inputStream = context.getResources().getAssets().open(fileName);
//inputStream = context.getResources().getAssets().open(fileName);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return inputStream;
}
private InputStream readDataFromInternet(String urlPath)
{
//从网络上获取实时数据
URL urlInfo = null;
InputStream inputStream = null;
try {
urlInfo = new URL(urlPath);
URLConnection connection = urlInfo.openConnection();
HttpURLConnection httpConnection = (HttpURLConnection)connection;
// 单位是毫秒,设置超时时间为5秒
httpConnection.setConnectTimeout(5*1000);
// HttpURLConnection是通过HTTP协议请求path路径的,所以需要设置请求方式,可以不设置,因为默认为GET
httpConnection.setRequestMethod("GET");
int responseCode = httpConnection.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK)
{
inputStream = httpConnection.getInputStream();
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return inputStream;
}
}