将xml的属性读取成html标签,Android xml数据的读取和写入(sax,pull,dom,xstream,jsoup)...

一、引用

文内相关其他XStream解析xml数据

二、数据格式

1、xml数据

包含单个数据,列表数据,bean数据。有tag,attribute,content-text

以下我们就是我们要读取和写入的数据

* <?xml version='1.0' encoding='utf-8' standalone='yes' ?>

*

*

*

*

* 仪器123

* 188

* YYY

* 检测兽药残留

*

*

* 仪器456

* 199

* XXX

* 检测农药残留及多参数

*

*

*

2、bean

public class DeviceInfo {

String name;

int id;

int price;

String company;

String usage;

public DeviceInfo(){}

public DeviceInfo(String name,int id,int price,String company,String usage){

this.name = name;

this.id = id;

this.price = price;

this.company = company;

this.usage = usage;

}

//省略get,set,tostring...

}

三、写入

1、XmlSerializer - xml序列,本质是pull

1.1、设置输出文件流FileOutputStream,xml序列号,文本格式...

1.2、startTag和endTag为一个元素的开始和结束标志

1.3、attribute 是当前tag的属性,一般来说bean的元素都可以放在里面

1.4、text 是tag的content-text,就是文本值

1.5、关闭xml序列文本、关闭FileOutputStream

/**写入XML数据*/

private void WriteXmlToSdcardByXmlSerial(){

List deviceInfoList = new ArrayList<>();

DeviceInfo deviceInfo = new DeviceInfo("仪器123",1,188,"YYY","检测兽药残留");

DeviceInfo deviceInfo3 = new DeviceInfo("仪器456",2,199,"XXX","检测农药残留及多参数");

deviceInfoList.add(deviceInfo);

deviceInfoList.add(deviceInfo3);

try {

//-------内部-----------

// // 指定流目录

// OutputStream os = openFileOutput("persons.xml", Context.MODE_PRIVATE);

// // 设置指定目录

// serializer.setOutput(os, "UTF-8");

//--------外部---------

//xml文件的序列号器 帮助生成一个xml文件

FileOutputStream fos = new FileOutputStream(new File(xmlPath));

//获取到xml的序列号

XmlSerializer serializer = Xml.newSerializer();

//序列化初始化

serializer.setOutput(fos, "utf-8");

//创建xml

serializer.startDocument("utf-8", true);

//顶层element有且只有一个

serializer.startTag(null,"xml_data");

//tag+attribute:

//tag+text:wujn

serializer.startTag(null,"user");

serializer.attribute(null,"name","wujn");

//serializer.text("wujn");

serializer.endTag(null,"user");

//多组...

serializer.startTag(null,"deviceinfos");

for(int i=0;i

serializer.startTag(null,"deviceinfo");

serializer.attribute(null,"id",String.valueOf(deviceInfoList.get(i).getId()));

serializer.startTag(null,"name");

serializer.text(deviceInfoList.get(i).getName());

serializer.endTag(null,"name");

serializer.startTag(null,"price");

serializer.text(String.valueOf(deviceInfoList.get(i).getPrice()));

serializer.endTag(null,"price");

serializer.startTag(null,"company");

serializer.text(deviceInfoList.get(i).getCompany());

serializer.endTag(null,"company");

serializer.startTag(null,"usage");

serializer.text(deviceInfoList.get(i).getUsage());

serializer.endTag(null,"usage");

serializer.endTag(null,"deviceinfo");

}

serializer.endTag(null,"deviceinfos");

//顶层element有且只有一个

serializer.endTag(null,"xml_data");

//关闭文档

serializer.endDocument();

//写入流关闭

fos.flush();

fos.close();

ToastUtil.showShort(instance,"xml数据已导出");

} catch (IllegalArgumentException e) {

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());

} catch (IllegalStateException e) {

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());

} catch (IOException e) {

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());

}

}

2、Document - dom形式

1.1、DocumentBuilderFactory工厂新建一个document

1.2、createElement 新建元素,里面放的是tag值

1.3、setAttribute 设置attribute,一般bean类数据可放这里

1.4、setTextContent 是tag的content-text,就是文本值

1.5、appendChild 添加节点元素,一层层自己控制

1.6、Transformer 把document转成String

1.7、FileOutputStream 打开,写入String.getBytes(),关闭流

/**写入XML数据*/

private void WriteXmlToSdcardByDom(){

List deviceInfoList = new ArrayList<>();

DeviceInfo deviceInfo = new DeviceInfo("仪器123",1,188,"YYY","检测兽药残留");

DeviceInfo deviceInfo3 = new DeviceInfo("仪器456",2,199,"XXX","检测农药残留及多参数");

deviceInfoList.add(deviceInfo);

deviceInfoList.add(deviceInfo3);

try {

DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();

DocumentBuilder documentBuilder = null;

documentBuilder = documentBuilderFactory.newDocumentBuilder();

Document document = documentBuilder.newDocument();

document.setXmlStandalone(true);

document.setXmlVersion("1.0");

//根节点

Element root = document.createElement("xml_data");

//user节点

Element userE = document.createElement("user");

userE.setAttribute("name","wujn");

root.appendChild(userE);

//deviceinfos节点

Element devsE = document.createElement("deviceinfos");

for(int i=0;i

//单个deviceinfo节点

Element devE = document.createElement("deviceinfo");

devE.setAttribute("id",String.valueOf(deviceInfoList.get(i).getId()));

Element nameE = document.createElement("name");

nameE.setTextContent(deviceInfoList.get(i).getName());

devE.appendChild(nameE);

Element priceE = document.createElement("price");

priceE.setTextContent(String.valueOf(deviceInfoList.get(i).getPrice()));

devE.appendChild(priceE);

Element companyE = document.createElement("company");

companyE.setTextContent(deviceInfoList.get(i).getCompany());

devE.appendChild(companyE);

Element usageE = document.createElement("usage");

usageE.setTextContent(deviceInfoList.get(i).getUsage());

devE.appendChild(usageE);

//添加deviceinfo节点

devsE.appendChild(devE);

}

root.appendChild(devsE);

document.appendChild(root);

TransformerFactory transformerFactory = TransformerFactory.newInstance();

Transformer transformer = transformerFactory.newTransformer();

//转成string

transformer.setOutputProperty("encoding","utf-8");

StringWriter stringWriter = new StringWriter();

transformer.transform(new DOMSource(document),new StreamResult(stringWriter));

LogUtil.i("xml stream = "+stringWriter.toString());

//xml文件的序列号器 帮助生成一个xml文件

FileOutputStream fos = new FileOutputStream(new File(xmlPath));

fos.write(stringWriter.toString().getBytes());

//写入流关闭

fos.flush();

fos.close();

ToastUtil.showShort(instance,"xml数据已导出");

} catch (IllegalArgumentException e) {

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());

} catch (IllegalStateException e) {

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());

} catch (IOException e) {

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());

}catch (ParserConfigurationException e) {

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());

}catch (TransformerConfigurationException e) {

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());

}catch (TransformerException e) {

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());

}

}

四、读取

1、XmlPullParser - Pull形式,一行行解析的,减少内存消耗

1、xml解析器设置解读编码和FileInputStream

2、getEventType 获得tag标签类型,按照不同类型进行解析

XmlResourceParser.END_DOCUMENT

XmlResourceParser.START_TAG

XmlResourceParser.TEXT - 标签内文本content-text

XmlResourceParser.END_TAG

3、next() 下一行,还有nextTag,nextText等

5、数据整合

6、关闭FileInputStream流

注意://如果xml节点确定是文本,需要检查XmlResourceParser.TEXT,防止getText() 返回 null。

/**

* XmlPullParser - 读取XML数据

* 逻辑上有可能有不严谨的地方

* */

private void ReadXmlFromSdcardByPull(){

File xmlFile = new File(xmlPath);

if(xmlFile.exists()){

try {

StringBuilder sb = new StringBuilder();

sb.append(" -- XmlPullParser --\n");

List deviceInfoList = new ArrayList<>();

DeviceInfo deviceInfo = null;

boolean convertDeviceInfo = false;

//文件写入流

FileInputStream fis = new FileInputStream(xmlFile);

//xml解析

XmlPullParserFactory factory = XmlPullParserFactory.newInstance();

factory.setNamespaceAware(true);

XmlPullParser xrp = factory.newPullParser();

//设置input encode

xrp.setInput(fis, "UTF-8");

while (xrp.getEventType() != XmlResourceParser.END_DOCUMENT) {

if (xrp.getEventType() == XmlResourceParser.START_TAG) {

String tagName = xrp.getName();

if (tagName.equals("user")) {

String name = xrp.getAttributeValue(null, "name");

sb.append("user.name="+name+"\n");

}

else if(tagName.equals("deviceinfos")){

//nothing to do

}

else if(tagName.equals("deviceinfo")){

deviceInfo = new DeviceInfo();

int id = Integer.parseInt(xrp.getAttributeValue(null, "id"));

deviceInfo.setId(id);

LogUtil.d("id="+id);

convertDeviceInfo = true;

}

//解析 DeviceInfo

//text 是三个元素

if(convertDeviceInfo){

if(tagName.equals("name")) {

xrp.next();

//必须检查如果当前 xml 节点是文本,以便 getText() 不会返回 null。

if (xrp.getEventType() == XmlResourceParser.TEXT){

String name = xrp.getText();

deviceInfo.setName(name);

LogUtil.d("name="+name);

}

xrp.next();

}

else if(tagName.equals("price")){

xrp.next();

if (xrp.getEventType() == XmlResourceParser.TEXT){

int price = Integer.parseInt(xrp.getText());

deviceInfo.setPrice(price);

LogUtil.d("price="+price);

}

xrp.next();

}

else if(tagName.equals("company")){

xrp.next();

if (xrp.getEventType() == XmlResourceParser.TEXT){

String company = xrp.getText();

deviceInfo.setCompany(company);

LogUtil.d("company="+company);

}

xrp.next();

}

else if(tagName.equals("usage")){

xrp.next();

if (xrp.getEventType() == XmlResourceParser.TEXT){

String usage = xrp.getText();

deviceInfo.setUsage(usage);

LogUtil.d("usage="+usage);

}

xrp.next();

}

}

}

else if(xrp.getEventType() == XmlResourceParser.END_TAG){

String tagName = xrp.getName();

if(tagName.equals("deviceinfo")){

deviceInfoList.add(deviceInfo);

deviceInfo = null;

convertDeviceInfo = false;

}

}

//xrp.nextTag();

//xrp.nextText();

xrp.next();

}

//关闭流

fis.close();

fis=null;

for (int i=0;i

sb.append(deviceInfoList.get(i).toString()+"\n");

}

tv_result.setText(sb.toString());

} catch (IllegalArgumentException e) {

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());

} catch (IllegalStateException e) {

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());

} catch (IOException e) {

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());

} catch (XmlPullParserException e) {

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());

}

}else{

ToastUtil.showShort(instance,"xml文件不存在");

}

}

2、SAXParser - SAX形式

1、sax解析器设置FileInputStream 和解析助手handler

2、解析助手TestXmlHandler extends DefaultHandler

startDocument 开始文档

endDocument 结束文档

startElement 元素开始 :localName=tag标签名,attribute元素.getValue()获取元素值

endElement 元素结束

characters 元素内content-text

3、FileInputStream 刘关闭

注意:org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 76: junk after document element 这个异常是要么解析器解析写错了,要么就是xml文档不规范,比如顶层元素有多个,规定标准是只有一个顶层元素,在这里是xml_data

/**

* SAXParser - 读取XML数据

* 逻辑上有可能有不严谨的地方

*

* org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 76: junk after document element

* 顶层元素不止一个的异常

* */

private void ReadXmlFromSdcardBySAX(){

File xmlFile = new File(xmlPath);

if(xmlFile.exists()){

try {

final StringBuilder sb = new StringBuilder();

sb.append(" -- SAXParser --\n");

//文件写入流

FileInputStream fis = new FileInputStream(xmlFile);

SAXParserFactory spf = SAXParserFactory.newInstance();

SAXParser saxParser = spf.newSAXParser();//创建解析器

//设置解析器的相关特性,http://xnl.org/sax/features/namespaces = true;

//表示开启命名空间特性

//saxParser.setProperty("http://xnl.org/sax/features/namespaces", true);

TestXmlHandler handler = new TestXmlHandler() {

@Override

void onStart() {

LogUtil.i("SAXParser onStart >>> ");

}

@Override

void onEnd(String username, List deviceInfoList) {

LogUtil.i("SAXParser onEnd >>> ");

sb.append("user.name="+username+"\n");

for (int i=0;i

sb.append(deviceInfoList.get(i).toString()+"\n");

}

tv_result.setText(sb.toString());

}

};

saxParser.parse(fis, handler);

// InputSource inputSource = new InputSource();

// inputSource.setEncoding("utf-8");

// inputSource.setCharacterStream(new StringReader(xmlPath));

// saxParser.parse(new InputSource(new FileReader(new File(xmlPath))), handler);

//关闭流

fis.close();

fis=null;

}catch (IOException e){

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());

}catch (SAXException e){

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());

}catch (ParserConfigurationException e){

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());

}

}else{

ToastUtil.showShort(instance,"xml文件不存在");

}

}

/**

* TestXmlHandler - SAX的解析器

* 靠preTag也可以达到convertDeviceInfo类似的效果

* */

abstract class TestXmlHandler extends DefaultHandler{

private String username = "";

private List deviceInfoList = new ArrayList<>();

private DeviceInfo deviceInfo = null;

private boolean convertDeviceInfo = true;

private String preTag;//之前tag

@Override

public void startDocument() throws SAXException {

onStart();

}

@Override

public void endDocument() throws SAXException {

onEnd(username, deviceInfoList);

}

abstract void onStart();

abstract void onEnd(String username,List deviceInfoList);

@Override

public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

LogUtil.d("startElement: uri="+uri+", localName="+localName+", qName="+qName);

preTag = localName;

if("user".equals(localName)){

username = attributes.getValue("name");

}

else if("deviceinfos".equals(localName)){

//will be more deviceinfo

}

else if("deviceinfo".equals(localName)){

deviceInfo = new DeviceInfo();

int id = Integer.parseInt(attributes.getValue("id"));

deviceInfo.setId(id);

convertDeviceInfo = true;

}

}

@Override

public void endElement(String uri, String localName, String qName) throws SAXException {

LogUtil.d("endElement: uri="+uri+", localName="+localName+", qName="+qName);

preTag = null;

if("deviceinfo".equals(localName)){

deviceInfoList.add(deviceInfo);

deviceInfo = null;

convertDeviceInfo = false;

}

}

@Override

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

String data = new String(ch,start,length);

LogUtil.d("characters: preTag="+preTag+", data="+data);

if(convertDeviceInfo){

if(preTag.equals("name")) {

deviceInfo.setName(data);

LogUtil.d("name="+data);

}

else if(preTag.equals("price")){

int price = Integer.parseInt(data);

deviceInfo.setPrice(price);

LogUtil.d("price="+price);

}

else if(preTag.equals("company")){

deviceInfo.setCompany(data);

LogUtil.d("company="+data);

}

else if(preTag.equals("usage")){

deviceInfo.setUsage(data);

LogUtil.d("usage="+data);

}

}

}

}

3、Document - dom形式:此方式需要读取整个流数据,占用内存较大,一般针对小型xml数据可以用此方法,有点在于简单易懂

1、document加载输入流

2、getElementsByTagName 获得该tag名下的所有节点

3、每个node(Element)都有获取属性,属性name和值.getAttributes().getNamedItem("name").getNodeValue()

4、每个node(Element)的文本值 content-text : getTextContent();

5、关闭输入流

/**

* Document - 读取XML数据

* 直观明了,但是要预加载所有数据,对xml比较大占内存比较多

* */

private void ReadXmlFromSdcardByDom(){

File xmlFile = new File(xmlPath);

if(xmlFile.exists()){

try {

StringBuilder sb = new StringBuilder();

sb.append(" -- Document --\n");

DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();

DocumentBuilder documentBuilder = null;

documentBuilder = documentBuilderFactory.newDocumentBuilder();

//加载输入流到document中

//InputStream inputStream = getAssets().open("person.xml");

FileInputStream fis = new FileInputStream(xmlFile);

Document document = documentBuilder.parse(fis);

NodeList userNodes = document.getElementsByTagName("user");

for(int i=0;i

sb.append("user.name="+userNodes.item(i).getAttributes().getNamedItem("name").getNodeValue()+"\n");

}

List deviceInfoList = new ArrayList<>();

DeviceInfo deviceInfo = null;

NodeList deviceNodes = document.getElementsByTagName("deviceinfo");

//设备节点

for(int i=0;i

deviceInfo = new DeviceInfo();

Node deviceNode = deviceNodes.item(i);

int id = Integer.parseInt(deviceNode.getAttributes().getNamedItem("id").getNodeValue());

LogUtil.d("id="+id);

deviceInfo.setId(id);

NodeList eachDeviceNodes = deviceNode.getChildNodes();

LogUtil.d("eachDeviceNodes.length="+eachDeviceNodes.getLength());

//设备下值节点

for(int j=0;j

String tagName = eachDeviceNodes.item(j).getNodeName();//nodename not localname

LogUtil.d("tagName=" + tagName);

String data = eachDeviceNodes.item(j).getTextContent();

if (tagName.equals("name")) {

deviceInfo.setName(data);

LogUtil.d("name=" + data);

} else if (tagName.equals("price")) {

int price = Integer.parseInt(data);

deviceInfo.setPrice(price);

LogUtil.d("price=" + price);

} else if (tagName.equals("company")) {

deviceInfo.setCompany(data);

LogUtil.d("company=" + data);

} else if (tagName.equals("usage")) {

deviceInfo.setUsage(data);

LogUtil.d("usage=" + data);

}

}

//添加设备到列表

deviceInfoList.add(deviceInfo);

}

//关闭流

fis.close();

fis=null;

for (int i=0;i

sb.append(deviceInfoList.get(i).toString()+"\n");

}

tv_result.setText(sb.toString());

}catch (IOException e){

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());

}catch (ParserConfigurationException e){

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());

}catch (SAXException e){

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());

}

}else{

ToastUtil.showShort(instance,"xml文件不存在");

}

}

4、Jsoup- 和上面dom类似

1、Jsoup.parse 、Jsoup.connect 加载url或者htmlstring或者文件

2、getElementsByTag 获得该tag名下的所有节点,

3、children() 获得某节点元素下的所有元素

4、每个Element都有获取属性,attr(key)

5、每个Element的文本值 content-text : text();

compile 'org.jsoup:jsoup:1.9.2'

/**

* Jsoup - 读取XML数据(本质是document)

* 直观明了,但是要预加载所有数据,对xml比较大占内存比较多

* */

private void ReadXmlFromSdcardByJsoup(){

File xmlFile = new File(xmlPath);

if(xmlFile.exists()){

try {

StringBuilder sb = new StringBuilder();

sb.append(" -- Jsoup --\n");

//url网址作为输入源

//Document doc = Jsoup.connect("http://www.example.com").timeout(60000).get();

//File文件作为输入源

//File input = new File("/tmp/input.html");

//Document doc = Jsoup.parse(input, "UTF-8", "http://www.example.com/");

org.jsoup.nodes.Document document = Jsoup.parse(xmlFile, "UTF-8");

org.jsoup.select.Elements userE = document.getElementsByTag("user");

for(int i=0;i

sb.append("user.name="+userE.get(i).attr("name")+"\n");

}

List deviceInfoList = new ArrayList<>();

DeviceInfo deviceInfo = null;

org.jsoup.select.Elements deviceE = document.getElementsByTag("deviceinfo");

//设备节点

for(int i=0;i

deviceInfo = new DeviceInfo();

org.jsoup.nodes.Element devE = deviceE.get(i);

int id = Integer.parseInt(devE.attr("id"));

LogUtil.d("id="+id);

deviceInfo.setId(id);

org.jsoup.select.Elements eachDeviceElements = devE.children();

LogUtil.d("eachDeviceElements.length="+eachDeviceElements.size());

//设备下值节点

for(int j=0;j

String tagName = eachDeviceElements.get(j).tagName();

String data = eachDeviceElements.get(j).text();

LogUtil.d("tagName=" + tagName + ", text="+data);

if (tagName.equals("name")) {

deviceInfo.setName(data);

} else if (tagName.equals("price")) {

int price = Integer.parseInt(data);

deviceInfo.setPrice(price);

} else if (tagName.equals("company")) {

deviceInfo.setCompany(data);

} else if (tagName.equals("usage")) {

deviceInfo.setUsage(data);

}

}

//添加设备到列表

deviceInfoList.add(deviceInfo);

}

//关闭流

//fis.close();

//fis=null;

for (int i=0;i

sb.append(deviceInfoList.get(i).toString()+"\n");

}

tv_result.setText(sb.toString());

}catch (IOException e){

e.printStackTrace();

ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());

}

}else{

ToastUtil.showShort(instance,"xml文件不存在");

}

}

五、读取和写入文本

/**

* 从file文件中读取string来

* */

public static String readFromFile(String fPath) throws IOException{

BufferedReader bf = new BufferedReader(new FileReader(fPath));

String content = "";

StringBuilder sb = new StringBuilder();

while (content != null) {

content = bf.readLine();

if (content == null) {

break;

}

sb.append(content.trim());

}

bf.close();

return sb.toString();

}

/**

* 写string到file文件中

* */

public static void writeToFile(String content,String fPath)throws IOException{

File txt = new File(fPath);

if (!txt.exists()) {

txt.createNewFile();

}

FileOutputStream fos = new FileOutputStream(txt);

fos.write(content.getBytes());

fos.flush();

fos.close();

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值