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

来源:互联网 发布:网络好声音第二季 编辑:程序博客网 时间:2024/06/04 20:02

一、 初次邂逅 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测试
这里写图片描述

0 0
原创粉丝点击