您的位置:首页 > 编程语言 > Java开发

java眼中的XML---文件读取

2016-06-16 16:29 621 查看
一、 初次邂逅 XML

(一)、xml简介

1、xml文件以.xml为扩展名

2、存储:树形结构

3、用于不同平台、不同设备间的数据共享通信

(二)、【扫盲】

1、< book id=”1”>< /book> id为属性, < book>< id>1< /id>< /book> id为节点

2、xml文件中根据自己的需要定义里面要保存的数据的类型和标签,但是在开头要进行声明,即要加上版本信息和编码方式< ?xml version=”1.0” encoding=”UTF-8”?>

XML作用:

不同应用程序之间通信、传输信息(订票程序和支付程序)

不同系统间的通信(例:Windows系统和IOS系统)

不同平台间的数据共享(手机端和PC端)

不同APP之间的通信,不同的平台间的通信,不同平台间的数据共享。XML文件主要用于存储以及传输信息。

通过xml文件存储小型数据。



二、应用DOM方式解析XML

2-1 如何进行 XML 文件解析前的准备工作

获取xml文件内容也就时解析XML文件

四种解析方式:DOM SAX DOM4J JDOM

DOM、SAX :java 官方方式,不需要下载jar包

DOM4J、JDOM :第三方,需要网上下载jar包

DOM使用步骤:

准备工作

1、创建一个DocumentBuilderFactory的对象

DocumentBuilderFactory dbf = DocumnetBuilderFactory.instance();

2、创建一个DocumentBuilder的对象

DocumentBuilder db = dbf.newDocumentBuilder();

3、通过DocumentBuilder对象的parse方法加载xml文件到当前项目

Document document = db.parse(“*.xml”);

2-2 使用 DOM 解析 XML 文件的属性名和属性值

使用Dom解析xml文件的属性节点。

在不知道节点属性的个数和属性名时:

1、通过document.getElementByTagName(“标签名”)获得所有标签名的节点,得到一个NodeList集合

2、通过NodeList.getLength()获得集合长度,遍历集合

3、Node node = NodeList.item(index)获得里面的节点

4、通过NamedNodeMap attrs = node.getAttributes()获取所有属性集合

5、通过attrs.getLength()遍历集合,Node attr = atrrs.item(index)

6、attr.getNodeName()获得属性名,attr.getNodeValue()获取属性值

前提已经知道book节点有且只有1个id属性,将book节点进行强制类型转换,转换成element类型。

1、通过document.getElementByTagName(“标签名”)获得所有标签名的节点,得到一个NodeList集合

2、通过NodeList.getLength()获得集合长度,遍历集合

3、element book=(element)bookList.item(i);//强制转换为element类型

4、string attrValue = book.getAttribute(“id”);



2-3 使用 DOM 解析XML 文件的节点名和节点值

解析文件节点以及子节点的值

1.先获取子节点,Node下有方法getChildNodes()来获取某个节点的子节点的集合,返回NodeList类型.

NodeList childNodes=book.getChildNodes()//包含book节点所有的子节点,两个标签之间的所有内容都看成是子节点.

2.通过childNodes的getLength()方法返回字点的个数(空格与换行字符看成为一个文本节点,标签与结束标签看成一个元素节点)

3.通过NodeList的item(i)获取指定位置子节点的名称返回Node类型.再用Node类型的getNodeName()方法就可以获取节点名

Node childnode=childNodes.item(i);

String name=childnode.getNodeName();

可以通过Node类的getNodeType()来区分文本类型的node以及元素类型的node,看当前Node类型是否与Node.”节点类型英文全称”相同.

if(childnode.getNodeType==Node.ELEMENT_NODE)

{System.out.println(name)}

4.不能直接通过Node的getNodeValue()来获取节点的值,因为元素节点的nodeValue的返回值为null而且标签之间的文本被看做是该标签的子节点.所以要用Node的getFirstChild()此时获取的子节点为文本节点,Text节点类型的nodeValue返回值为节点内容,再getNodeValue()。

或者直接用Node的getTextContent()方法直接获取节点值。

如果该Node节点还存在其他子节点并且有节点值< name>< a>广州大学< /a>华软学院< /name>,那么用getFirstChild().getNodeValue()一样是null,因为获取的子节点仍然是element类型的

如果用Node的getTextContent(),一样会把< a>元素节点当成是Content输出。 结果为广州大学华软学院.

三、应用SAX方式解析XML

3-1 使用 SAX 解析 XML 文件的开始和结束

DOM解析原理:

先把XML文件整个加载到内存中,在逐个解析。

SAX解析原理:

通过自己创建的Handler类,去逐个分析遇到的每一个节点;(节点分析是从最外层向里层逐个开始)

遇到bookstore节点就可以进行处理了,但是bookstore没有属性所以就不对其做更多的处理了

遇到book节点时,book节点是拥有的id属性,会通过startElement来处理book节点的id属性

遇到book节点的子节点name节点,它没有必要处理name的属性,但name是个ElementNode类型的节点,它会获取name的节点名和节点值,执行完name节点后会通过endElement方法执行name节点的结束标签

SAX方式解析xml步骤

1.通过SAXParserFactory的静态newInstance()方法获取一个SAXParserFactory的对象。

2.通过SAXParserFactory对象的newSAXParser()方法返回一个SAXParser类的对象。

3.创建一个类继承DefaultHandler,重写其中的一些方法并创建类的实例.

4.通过SAXParser类的Parse(Stringname,df)方法解析xml文件,参数Stringname为路径名,df为继承于DefaultHandler类的实例化对象,不需要定义变量存储返回的类型.

SAX是按节点顺序进行解析,遇到xml的声明即开始解析,遇到最后一个节点的尾节点便结束解析,需要用户自己定义一个类继承于DefaultHandler类来解析,遇到开始标签节点便通过startElement开始解析节点,遇到结束标签节点便通过endElement结束解析,再遇到开始节点继续通过startElement解析,一直循环直到xml文件最后的结束标签节点.

5.在继承于DefaultHandler这个类中需要重写父类的startElement()和endElement()方法,来进行开始节点与结束节点的解析,再重写startDocument()方法与endDocument()方法来标识解析的开始与结束.

3-2 使用 SAX 解析 XML 文件的节点属性

handler重写:

获取xml解析开始、结束

startDocument() endDocument()

获取xml的标签

开始:startElement(String uri, String localName, String qName,Attributes attributes)

获取属性名:attributes.getQName(i);获取属性值:attributes.getValue(i)

结束:endElement(String uri, String localName, String qName)

获取节点值

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

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

已知节点的属性名的情况下

if(qname.equals(“book”)){

String value = attributes.getValue(“id”);

}

4.不知节点的属性名的情况下

获取属性长度

int length=attributes.getLength();

获取属性名和属性值

for(int i=0;i< length;i++){

System.out.print(attributes.getQname(index)+attributes.getValue(index));

}

3-3 使用 SAX 解析 XML 文件的节点名和节点间文本

SAX解析XML的速度比DOM的块,

SAX的解析XML的解析器,需要重写startElement()开始解析的方法and endElemaent()方法 结束解析的方法and characters()方法

重写charaters()方法时,String(byte[] bytes,int offset,int length)的构造方法进行数组的传递

再去除解析时多余空格

if(!value.trim().equals(“”)){

System.out.println(value);

}

使用 SAX 解析 XML 文件的节点名和节点间文本

startElement方法——String qName(第三个参数):节点名

startElement方法——Attributes attributes(第四个参数):节点名的属性操作

characters方法——char[] ch(第一个参数):xml整个文本内容,所以需截取想要的内容

如图代码+以下代码

public void endElement(String uri, String localName, String qName)

throws SAXException {

//调用DefaultHandler类的endElement方法

super.endElement(uri, localName, qName);

//判断是否针对一本书已经遍历结束

if (qName.equals(“book”)) {

System.out.println(“======================结束遍历某一本书的内容=================”);

}

}

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

super.characters(ch, start, length);

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

if (!value.trim().equals(“”)) {

System.out.println(“节点值是:” + value);

}

}

执行顺序。

1、SAXParserHandler类的执行顺序为:startDocument()开始Xml解析—>第一行,以后每行的执行顺序为——>startElement()—characters()—>endElemnet()—->到最后一行的< bookstore>—->endDcunment()。

3-4 使用 SAX 解析将 XML 的内容和结构存入 JAVA 对象

xml的SAX解析并

将解析的内容及xml结构形式保存至Java对象中。

SAX解析:

1、获取一个SAXParserFactory的实例:SAXParserFactory factory = SAXParserFactory.newInstance();

2、通过factory获取SAXParser实例:SAXParser parser = factory.newSAXParser();

3、创建SAXParserHandler对象:SAXParserHandler handler = new SAXParserHandler();

4、将xml文件和解析方式handler加载到SAXParser实例:parser.parse(“books.xml”,handler);

解析的时候,是startElement-characters-endElement , characters解析完一个属性,就到endElement,然后又解析一个属性又到endElement,最后解析完全部属性,到endElement又到startElement开始下一个节点。

ArrayList保存对象 ArrayList< Book> BookList=new ArrayList< Book>();

BookList.add(book);book=null;后继续遍历

public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException// qName是String类型节点名称;attributes是Attributes类型的实例,属性的意思;

四、应用JDOM和DOM4J解析XML

4-1 JDOM 开始解析前的准备工作

JDOM是第三方提供的解析XML方法,需要jdom-2.0.5.jar包(版本不断在更新)

步骤:

1、创建SAXBuilder对象

SAXBuilder saxBuilder = new SAXBuilder();

2、创建一个输入流将XML加载到输入流中

InputStream in = new FileInputStream(“src/person.xml”);

3、将xml加载到文件输入输入流中

Document document = saxBuilder.build(in);

4、根据Document对象获取xml中的根节点

Element rootEle = document.getRootElement();

5、获取根节点下的子节点的list集合

List< Element> personList = rootEle.getChildren();

Ps:小技巧:Alt+向上——代码上移,Alt+向下——代码下移;

4-2 应用 JDOM 解析节点属性

//通过增强for循环进行遍历子节点集合

for(Element person : personList){

System.out.print(“======开始解析第” + personList.indexOf(person)+1 + “个人======”);

//解析person的属性

List< Attribute> attrList = person.getAttributes();//适用于我们不知道里面有多少属性

person.getAttributeValue(“id”);//适用于我们知道子节点属性的名字直接获取其属性值

//遍历属性

for(Attribute attr : attrList){

//获取属性名

String attrName = attr.getName();

//获取属性值

String attrValue = attr.getValue();

System.out.print(“属性名:” + );

}

System.out.println(“======结束解析第” + personList.indexOf(person)+1 + “个人======”);

}

4-3 应用 JDOM 解析子节点的名和值

DOM 解析

获取节点名、值:getNodeName() getNodeValue() getTextContent()

获取子节点:getChildNodes() 返回 NodeList

获取属性节点:getAttributes() 返回 NamedNodeMap

JDOM 解析

获取节点名、值:getName() getValue()

获取子节点:getChildren() 返回 List< Element>

获取属性节点:getAttributes() 返回 List< Attribute>

4-4 JDOM 解析时乱码的处理

JDOM 解析时乱码的处理

两种方法可以解决乱码问题,

1:修改xml文件中的编码格式,

2:在解析中使用inputstreamreader()指定编码格式

// 2.创建一个输入流,将xml文件加载到输入流中

in = new FileInputStream(“src/res/books.xml”);

InputStreamReader isr = new InputStreamReader(in, “UTF-8”);

// 3.通过saxBuilder的build方法,将输入流加载到saxBuilder中

Document document = saxBuilder.build(isr);



Ps:注意先看下xml文件encoding是否修改编码方式后可以正常显示,若还是乱码,则考虑使用代码的方式将其转换。

处理中文乱码步骤:

1)修改xml文件的编码

2)将InputStream封装为一个InputStreamReader,并在InputStreamReader的构造函数中指定正确的编码,然后将InputStreamReader传入到SAXBuilder中就可以处理中文乱码了

利用代码问题解决局部乱码问题(需要利用InputStreamReader来解决)

(1)InputStream in=new FIleStream(“book.xml”);

(2)InputStreamReader isr = new InputStreamReader(in, “utf-8”);

(3)Document document = saxBuilder.build(isr);

4-5 在 JDOM 中存储 Book 对象

在 JDOM 中存储 Book 对象

private static ArrayList< Book> booksList = new ArrayList< Book>();



// 遍历attrList(针对不清楚book节点下属性的名字及数量)

for (Attribute attr : attrList) {

// 属性名

String attrName = attr.getName();

// 属性值

String attrValue = attr.getValue();

System.out.println(“属性名:” + attrName + “属性值:”

+ attrValue);

if (attrName.equals(“id”)) {

bookEntity.setId(attrValue);

}

}

// 对book节点的子节点的节点名及节点值的遍历

List< Element> bookChilds = book.getChildren();

for (Element child : bookChilds) {

System.out.println(“节点名:” + child.getName() + “节点值:”

+ child.getValue());

if (child.getName().equals(“name”)) {

bookEntity.setName(child.getValue());

}

else if (child.getName().equals(“author”)) {

bookEntity.setAuthor(child.getValue());

}

…//else if(){}与上面类似

booksList.add(bookEntity);

bookEntity = null;

syso.booksList.size();

syso.booksList.get(0).getId();

syso.booksList.get(0).getName();



4-6 关于 JDOM 使用过程中 JAR 包的引用

JDOM使用过程中JAR包的引用

我们的项目中直接配置build path指定的jar包如果是在我们PC的硬盘某个路径,那么在日后导出项目时候,项目中是没有jar包的。

我们只能在我们的项目下建立一个lib文件夹将所需jar包复制进去,再进行build path的配置即可。

操作:项目根目录下新建lib文件夹——复制—粘帖包——右击包选择“构建路径”——“添加至构建路径”即可。

4-7 应用 DOM4J 解析节点属性

DOM4J 解析 xml 文件

导入jar包

配置路径

1、创建一个 SAXReader 对象

SAXReader saxReader = new SAXReader();

2、将 xml 文件加载到 SAXReader 中,并获取 document 对象

Document document = saxReader.read(fileName);

3、通过 getRootElement() 获取根节点元素

Element employeeRoot = document.getRootElement();

4、通过 elementIterator() 获取子节点元素,返回 Iterator 返回迭代器

Iterator eles = eleRoot.elementIterator();

5、通过 while 遍历迭代器

while(eles.hasNest()){

Element ele = (Element)eles.next();}

6、获取属性节点类似 JDOM 解析

List< Attribute> attrs = ele.attributes();

7、获取元素节点名、值

ele.getName() ele.getStringValue()/ele.getText()

8、获取属性节点名、值

ele.getName() ele.geValue()

4-8 应用 DOM4J 解析子节点的信息

解析子节点的信息

Iterator itt = book.elementIterator();

while(itt.hasNext()){

Element bookchild = (Element)itt.next();

bookchild.getName();

bookchild.getStringValue();

}

五、四种XML解析方式大PK

5-1 四种解析方式的分析

基础方法:DOM(平台无关的官方解析方式)、SAX(基于事件驱动的解析方式)

扩展方法:JDOM、DOM4J(在基础的方法上扩展出的,只有在java中能够使用的解析方法)

DOM:一次性将整个xml文件加载到内存中,形成DOM树

优点:形成了树结构,直观好理解,代码更容易编写

解析过程中树结构保留在内存中,方便修改

缺点:当xml文件较大时,对内存消耗比较大,容易影响解析性能并造成内存溢出

SAX:逐条语句判断解析

优点:采用事件驱动模式,对内存消耗比较小

适用于只需要处理xml中数据时

缺点:不易编码

很难同时访问同一个xml中的多处不同数据

JDOM:仅使用具体类而不使用接口

API大量使用了Collections类

DOM4J:JDOM的一种智能分支,它合并了许多超出基本XML文档表示的功能

DOM4J使用接口和抽象基本类方法,是一个优秀的Java XML API

具有性能优异、灵活性好、功能强大和极端易使用的特点

是一个开放源代码的软件

5-2 四种解析方式解析速度分析

JUnit是Java提供的一种进行单元测试的自动化工具。测试方法可以写在任意类中的任意位置。使用JUnit可以没有main()入口进行测试,在方法之前标注@text注解。

DOM4J在灵活性和对复杂xml的支持上都要强于DOM

DOM4J的应用范围非常的广,例如在三大框架的Hibernate中是使用DOM4J的方式解析文件的。

DOM是w3c组织提供的一个官方解析方式,在一定程度上是有所应用的。

当XML文件比较大的时候,会发现DOM4J比较好用。

工程右键Build path–add library–JUnit单元测试–verion:JUnit4

JUnit测试

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: