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

JAVA中的XML文件--文件读取(上)

2016-06-27 23:50 471 查看
菜鸟一只,最近一直在慕课网上学习java,结合自己的理解并且在网上查找相关讲解,将自己的学习笔记整理出来与大家分享一下,菜鸟就能不断进步。

1 XML文件简介

XML是可扩展标记语言(Extensible Markup Language)的缩写,其中Markup是关键部分,可以创建内容,然后使用限定标记标记它,从而使每个单词、短语或块成为可识别、可分类的信息。

1.1 XML文件是以树形结构存储

<根元素名称>
<子元素名 属性 = "属性值"
……    ……>
<子元素名>****</子元素名>

……  ……  ……

<子元素名>****</子元素名>
</子元素名>

…… …… ……

</根元素名称>


PS:

1. 相同元素名的不同元素属性和其子元素可以不同.

2. XML 文件由内容和标记组成,将内容文本包含到元素中,即分别在文本的首末两端添加开始和结束标记<元素名>文本

1.2 在XML文件首行声明–可选部分

它将文件识别为 XML 文件,有助于工具和人类识别XML,这个声明必须出现在文件的开头

<?xml version = "1.0" encoding = 编码格式(eg."UTF-8")?>


1.3 用途

解决不同程序、不同平台、不同操作系统的通讯问题。

2 JAVA中解析XML文件

在java中有四种解析XML文件的方式:DOM,SAX,DOM4J,JDOM。前两个是官方提供的,不需要额外的jar包

以student.xml文件为例:

<?xml version = "1.0" encoding = "UTF-8" ?>
<school>
<student id = "0001">
<name>王明</name>
<sex>男</sex>
<major>计算机科学与技术</major>
</student>
<student id = "0002">
<name>李红</name>
<sex>女</sex>
<major>计算数学</major>
</student>
</school>


2.1 应用DOM方式解析XML

2.1.1 准备工作

创建一个DocumentBuilderFactory对象:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();


创建一个DocumentBuilder对象:

DocumentBuilder db = dbf.newDocumentBuilder()


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

Document document = db.parse("*****.xml");


说明:

1. newInstance()是DocumentBuilderFactory的静态方法,用于获取DocumentBuilderFactory的一个实例;

2. newDocumentBuilder()用于获取DocumentBuilder的对象;

3. parse()方法是org.w3c.dom中的方法;

4. 注意捕捉异常。

2.1.2 获取元素(元素)的属性名和属性值

Document中的getElementByTagName(“student”)方法根据给定的元素名来获取该元素组成的集合,返回为NodeList类型(stuList):

NodeList stuList = document.getElementByTagName("student");


通过item(int index)方法遍历stuList中的每个元素,返回Node类型:

Node stu = stuList.item(i);


获得了每个元素后就可以获得进一步得到每个元素的属性,通过getAttributes()方法获得一个所有属性和属性值的映射NamedNodeMap:

NamedNodeMap attr = stu.getAtrributes();


同样的,属性映射attr通过item(index)方法获得每个属性,显然将返回一个Node类型:

Node attrnode = atts.item(i);


这时我们要进一步得到每个属性(attrnode)的名字和属性值,分别通过getNodeName()和getNodeValue()方法。

同时,注意到元素student除了有属性外,还有许多子元素(name,major等),如何获取呢?

通过getChildNodes()方法获取子元素的集合,和前面类似,返回值也是NodeList类型。每个元素中包含的文本也被看作是该元素的子元素,获取每个元素包含的文本可以通过getNodeValue()方法获取。

备注:

1. 常用的元素类型:

类型NodeTypeNamed ConstantnodeName/nodeValue
Element1ELEMENT_NODEelement name / null
Attr2ATTRIBUTE_NODEattribute name / attribute value
Text3TEXT_NODEtext / node text
由标记包含的元素(school、student、name等)的类型就是Element,元素的属性就是Attr类型,元素中的文本内容和xml元素间的空格等就是Text类型

2. 因为空格也会被看作是元素,所以获取我们所需要的元素时,应注意避免获取空格,我们可以通过判断得到的元素类型来避免空格:

node.getNodeType() == Node.ELEMENT_NODE;


3. 获取每个元素中的文本也可通过getTextContext()方法,它返回的是包括子元素的所有文本。

4. 可通过getFirstChild()方法获取元素的第一个子元素,可以和getTextContext()搭配使用。

2.1.3 代码示例如下:

public class DomTest {

public static void main(String[] args) {
//创建一个DocumentBuilderFactory对象
DocumentBuilderFactory dbf =  DocumentBuilderFactory.newInstance();
try {

4000
//创建一个DocumentBuilder对象
DocumentBuilder db = dbf.newDocumentBuilder();
//通过DocumentBuilder对象的parse方法加载books.xml到当前项目下
Document document = db.parse("students.xml");
//根据节点名获取所有该节点的集合
NodeList stuList = document.getElementsByTagName("student");
System.out.println("一共有"+stuList.getLength()+"个学生");
//遍历每一个student节点
for(int i = 0;i < stuList.getLength();++ i){
//通过item(i)方法获取一个节点
Node book = stuList.item(i);
NamedNodeMap atts =book.getAttributes();
System.out.println("第"+(i+1)+"个学生共有"+atts.getLength()+"个属性");
for(int j = 0; j < atts.getLength(); ++ j){
Node node = atts.item(j);
System.out.println(
node.getNodeName()+","+node.getNodeValue());
}
NodeList childNodes = book.getChildNodes();
System.out.println("共有"+childNodes.getLength()+"个子节点");
for(int j = 0;j < childNodes.getLength();++ j)
{
Node node = childNodes.item(j);
//区分出text类型的node以及element类型中的node
if(node.getNodeType() == Node.ELEMENT_NODE){
//获取element类型节点的节点名的三种方式
System.out.println( node.getNodeName()+","+
node.getChildNodes().item(0).getNodeValue());
System.out.println(node.getNodeName()+","+
node.getFirstChild().getNodeValue());
System.out.println(node.getNodeName()+","+
node.getFirstChild().getTextContent());
}
}
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
}catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}


2.2 应用SAX方式解析XML

SAX方式是通过DefaultHanlder逐行扫描XML文件内容,文档的读入过程也就是SAX的解析过程。

2.2.1 准备工作

使用SAXParserFactory的静态方法newInstance()获取 SAXParserFactory实例:

SAXParserFactory factory = SAXParserFactory.newInstance();


通过factory.newSAXParser()方法获取SAXParser实例:

SAXParser parser = factory.newSAXParser();


用parse()方法解析XML文件:

parser.parse("student.xml",DefaultHandler handler)


上一步中,我们需要一个DefaultHandler参数:

创建一个类继承DefaultHandler,重写其中的一些方法,进行业务处理并创建这个类的实例传给parse()方法

public class SAXParserHandler extends DefaultHandler


2.2.2 获取元素文本

在handler类中会重写如下几个方法:

startDocument()方法,文件解析开始使调用;

endDocument()方法,文件解析结束时调用;

startElement(String uri, String localName, String qName, Attributes attrs)方法

变量名表示
qName当前访问的元素名
attrs元素的属性
每访问一个元素都会调用该方法,如上表所述,qName可以得到 当前访问元素名,attrs保存了该元素的属性集合,可以通过getQName(index)和getQValue(index)方法遍历属性。

endElement(String uri, String localName, String qName)方法,当某个元素访问结束后调用;

characters(char[] ch, int start, int length)方法中,ch变量保存了整个xml文件内容,而start和length表示了当前访问元素文本的开始位置和长度,从而可将每个元素的文本内容保存到字符串中(根据程序执行结果,调用该方法是根据每个元素中文本和子元素的顺序调用的,如下代码的顺序:aaa ->root ->bbb)

<root>
<a>aaa</a>
root
<b>bbb</b>
<root>


但是需注意空格也将被看作子元素,所以应将全是空格的字符串筛选掉,可用trim()方法删除字符串左右两边的空格,然后判断剩余字符串是否是空(equals(“”))。

备注:

1.注意以上方法将抛出异常

不断学习不断总结^_^。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  JAVA XML DOM SAX