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

来源:互联网 发布:卖软件的网站 编辑:程序博客网 时间:2024/05/29 00:32

菜鸟一只,最近一直在慕课网上学习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. 常用的元素类型:

类型 NodeType Named Constant nodeName/nodeValue Element 1 ELEMENT_NODE element name / null Attr 2 ATTRIBUTE_NODE attribute name / attribute value Text 3 TEXT_NODE text / 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 {            //创建一个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.注意以上方法将抛出异常

不断学习不断总结^_^。。。

0 0
原创粉丝点击