大数据——Java XML技术

认识XML

XML是Extensible Markup Language即可扩展标记语言的缩写,是一种简单的数据存储语言,使用一系列简单的标记来描述数据。XML技术应用广泛,最基本的如网站、应用程序的配置信息一般都采用XML文件描述。
XML的特点如下:
XML与操作系统、编程语言的开发平台都无关。
规范统一。

XML文档结构

首先来了解XML文档结构,如下所示是描述图书信息的XML代码:

<?xml version="1.0" encoding="utf-8" ?>
<books>
    <!--图书信息-->
    <book id="bk101">
        <author>王珊</author>
        <title>.NET</title>
        <description>包含C#框架和网络编程等</description>
    </book>
    <book id="bk102">
        <author>李明明</author>
        <title>XML基础编程</title>
        <description>包含XMl基础概念和基本用法</description>
    </book>
</books>

XML声明

<?xml version="1.0" encoding="utf-8" ?>表明XML声明,用以标明该文件是一个XML文档。XML文档总是以XML声明开始,它定义了XML的版本和使用的编码格式等信息。

XML声明由以下几个部分组成:
version:文档符合XML1.0规范。
encoding:文档字符编码,默认为“UTF-8”
对于任何一个XML文档,其声明部分都是固定的格式。

标签

在XML中,用尖括号<>括起来的各种标签(Tag)来标记数据,标签需成对使用来界定字符数据,例如,王珊这一对标签中,是开始标签,是结束标签,“王珊”是标签描述的内容,表示作者信息。XML文件是可以包含任意数量的标签。

根元素

每个XML文档必须有且仅有一个根元素,如。
根元素的特点如下:
根元素是一个完全包括文档中其他所有元素的元素。
根元素的起始标签要放在所有其他元素的起始标签之前。
根元素的结束标签要放在所有其他元素的结束标签之后。

元素

XML文档的主要部分是元素,元素由开始标签、元素内容和结束标签组成。元素内容可以包含子元素、字符数据等。如王珊就是一个元素。
元素的命名规则如下:
名称中可以包含字母、数字或者其他字符。
名称不能以数字或者标点符号开始。
名称不能以字符xml(或者XML、Xml)开始。
名称中不能包含空格。

属性

在描述图书信息的XML文档中,标签使用id属性描述图书的标号信息。
属性定义语法格式如下:
<元素名 属性名 =“属性值”>
属性值用一对双引号包含起来。

XML中的特殊字符的处理

在XML中,有时在元素的文本中会出现一些特殊字符(如<、>、’、"、&),而XML文档结构本身就用到了这几个特殊字符,下面的办法,可以正确地解析包含特殊字符的内容:
对这5个特殊字符进行转义,也就是使用XML中的预定义实体代替这些字符,XML中的预定义实体和特殊字符的对应关系如下所示:

实体名称字符
&It<
&gt>
&amp&
&quot"
&apos

XML中的注释

注释的语法格式如下:

<!--注释内容-->

格式良好的XML文档

格式良好的XML文档需要遵循如下规则:
必须有XML声明语句。
必须有且仅有一个根元素。
标签大小写敏感。
属性值用双引号包括起来。
标签成对出现。
元素正确嵌套。

XML解析

在实际应用中,经常需要对XML文档进行各种操作。例如,在应用程序启动时读取XML配置文件信息,或者把数据库中的内容读取出来转换为XML文档形式,这时都会用到XML文档的解析技术。
目前常用的XML解析技术有4种。
(1) DOM
DOM是基于XML的树结构来完成解析的,DOM 解析XML文档时,会根据读取的文档,构建一个驻留内存的树结构,然后就可以使用DOM接口来操作这个树结构。因为整个文档的树结构是驻留在内存中的,所以各种操作非常方便。它还支持删除、修改、重新排列等多种操作。DOM解析XML的方式非常适用于多次访问XML的应用程序,但是DOM解析比较消耗资源。
(2) SAX
SAX是基于事件的解析,它是为了解决DOM解析的资源消耗问题而出现的。它不像DOM那样需要建立一棵完整的文档树, 而是通过事件处理器完成对文档的解折。因为SAX解析不用事先调入整个文档,所以它的优势就是资源占用少,内存消耗小。一般在解析数据量较大的XML文档时会采用这种方式。
(3) JDOM
JDOM的目的是直接为Java编程服务,利用纯Java技术对XML文档实现解析、生成、序列化及其他操作,把SAX和DOM的功能有效结合起来,简化与XML的交互并且比使用DOM更快。JDOM与DOM有两方面不同,首先,JDOM仅使用具体类而不使用接口,这在某些方面简化了API,但是也限制了灵活性;其次,API 大量使用了Collections类,简化了那些已经熟悉这些类的Java开发者的使用。JDOM的优势在于“使用20%的精力解决80%Java/XML的问题”。
(4) DOM4J
DOM4J是一个非常优秀的JavaXMLAPI,具有性能优异、功能强大和易用的特点,同时它也是一个开放源代码的软件。如今越来越多的Java软件都在使用DOM4J来读写XML,特别值得一提的是 Sun的JAXM也在使用DOM4J。
重点说明使用DOM和DOM4J两种方式解析XML。

使用DOM读取XML数据

DOM概念

DOM是Document Object Model即文档对象模型的简称,DOM把XML文件映射成一棵倒挂的“树", 以根元素为根节点,每个节点都以对象形式存在。通过存取这些对象就能够存取XML文档的内容。
例如,在C盘创建文件book xml并保存:

<?xml version="1.0" encoding="UTF-8"?>
<book>
	<title> 三国演义</title>
	<author>罗贯中</author>
	<price> >30</price>
</book>

Oracle公司提供了JAXP(Java API for XML
Processing)来解析XML。JAXP会把XML文档转换成一个DOM树。JAXP包含3个包,这3个包都在JDK中:
(1)org.w3c.dom: W3C 推荐的用于使用DOM解析XML文档的接口。
(2)org.xml.sax: 用于使用SAX解析XML文档的接口。
(3)javax.xml.parsers: 解析器工厂工具,程序员获得并配置特殊的分析器。
DOM解析使用到的类都在这些包中,在使用DOM解析XML时需要导入这些包中相关的类。

使用DOM读取手机收藏信息

使用DOM解析XML文档的步骤如下:
(1)创建解析器工厂对象,即DocumentBuilderFactory对象。
(2)由解析器工厂对象创建解析器对象,DocumentBuilder对象。
(3)由解析器对象对指定的XML文件进行解析,构建相应的DOM树,创建Document对象。
(4)以Document对象为起点对DOM树的节点进行增加、删除、修改、查询等操1下面通过示例3学习使用DOM读取XML数据。
示例一:
使用DOM读取手机收藏信息中的品牌和型号信息,XML文档代码如下:

<?xml version="1 .0" encoding="GB2312"?>
<PhoneInfo>
	<Brand name="华为">
	<Type name="U8650"/>
</Brand>
<Brand name="苹果">
	<Type name="iPhone4"/>
	<TvDe name="iPhone5"/>
	</Brand>
</PhoneInfo>

代码展示:

//得到DOM解析器的工厂实例
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
//从DOM工厂获得DOM解析器
DocumentBuilder db=dbf.newDocumentBuilder();
//解析XML文档,得到一个Document对象,即DOM树
Document doc=db.parse("‪D:/shuju/20200807-XML/src/PhoneInfo.xml);
//得到所有Brand节点列表信息
NodeList brandList=doc.getElementsByTagName("Brand");
//循环Brand信息
for (int i=0; i<brandList.getLength();i++) {
//获取第i个Brand元素信息
Node brand=brandList.item(i);
//获取第i个Brand元素的name属性的值
Element element=(Element) brand;
String attrValue= element.getAttribute("name");
//获取第i个Brand元素的所有子元素的name属性值
NodeList types=element.getChildNodes();
for (int j=0; j<types.getLength();j++){
	Element typeElement=((Element)types.item(j);//Type节点
	String type=typeElement.getAttribute("name");//获得手机型号
	System. out.printIn("手机: "attrValue+type);
	}
}

输出结果:
手机:华为U8650
手机:苹果iPhone4
手机:苹果iPhone5
使用DOM解析XML时主要使用到以下对象。
(1)Document对象
Document对象代表整个XML文档,所有其他的节点(Node) 都以一定的顺序包含在Document对象之内,排列成一个树状结构, 可以通过遍历这棵“树”来得到XML文档的所有内容。它也是对XML文档进行操作的起点,人们总是先通过解析XML源文件得到一个Document对象,然后再来执行后续的操作。Document 对象的主要方法如下:①getElementsByTagName(String name): 返回一个NodeList对象,它包含了所有指定标签名称的标签。
②getDocumentElement(): 返回一个代表这个DOM树的根节点的Element对象,也就是代表XML文档根元素的对象。
(2)NodeList对象
顾名思义,Nodeists 对象是指包含了一个或者多个节点的列表。可以简单地把它看成个Node数组。也可以通过方法来获得列表中的元素,Nex对象的常用方法如下:①getLength():返回列表的长度。
②item(int index):返回指定位置的Node对象。
(3)Node对象
Node对象是DOM结构中最基本的对象,代表了文档树中的一个抽象节点。在实际使用时,很少会真正用到Node对象,一般会用Element、Text等Node对象的子对象来操作文档。Node()对象的主要方法如下:
①getChildNodes():此节点包含的所有子节点的NoeList。
②geFirstChild(): 如果节点存在子节点,
③getLastChildl: 如果节点存在子节点,则返回第一个子节点。
④getNextSibling():返回DOM树中这个节点的下一个兄弟节点。
⑤getPreviousSibling():返回DOM树中这个节点的上一个兄弟节点。
⑥geNodeName(): 返回节点的名称。
⑦getNodeValue():返回节点的值。
⑧geiNodeType():返回节点的类型。
(4)Element对象
Element对象代表XML文档中的标签元素,继承自Node,也是Node最主要的子对象。在标签中可以包含属性,因而Element对象中也有存取其属性的方法。
①getAttribute(Strin attrbutename):返回标签中指定属性名称的属性的值。
②getElementsByTagName(String name):返回具有指定标记名称的所有后代Elements的NodeList。
注意:
XML文档中的空白字符也会被作为对象映射在DOM树中。因而,直接调用Node对象的getChildNodes()方法有时候会有些问题,有时不能够返回所期望的NodeList元素对象列表。
解决的办法如下:
①使用Element 的getElementsByTagName(String name)返回的NodeList就是所期待的对象。然后,可以用item()方法提取想要的元素。
②调用Node的getChildNodes()方法得到NodeList对象,每次通过item()方法提取Node对象后判断node.getNodeType()==Node.ELEMENT_NODE,即判断是否是元素节点,如果为true,则表示是想要的元素。
示例二:读取节点的文本值、
使用DOM读取手机新闻中的发布日期,XML文档代码如下:

<?xml version="1.0" encoding="GB2312" ?>
<PhoneInfo>
	<Brand name="华为">
		<Type name="U8650">
			<Item>
				<title>标题信息</title>
				<link>链接</link>
				<description>描述</description>
				<pubDate>2011-12-12</pubDate>
			</Item>
		</Type>
	</Brand>
</PhoneInfo>

首先观察DOM树结构,2011-12-12这个文本是作为putDate的子节点出现的,所以要读到这个日期,先要找到putDate节点,然后读取它的第一节点的值就可以了。
代码展示:

//得到DOM解析器的工厂实例
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
//从DOM工厂获得DOM解析器
DocumentBuilder db=dbf.newDocumentBuilder();
//解析XML文档,得到一个Document对象,即DOM树
Document doc=db.parse("src/收藏信息.xml");
//读取putDate
NodeList list=doc.getElementsByTagName("putDate");
//putDate元素节点
Element putDateElement=(Element)list.item(0);
//读取文本节点
String putDate=putDateElement.getFirstChild().getNodeValue();
System.out.print(putDate);

输出结果:2011-12-12

常用接口介绍

在这里插入图片描述

添加信息

实例三:

<?xml version="1 .0" encoding ="GB2312"?>
<PhoneInfo>
    <Brand name="华为">
        <Type name="U8650"/>
    </Brand>
    <Brand name="苹果">
        <Type name="iPhone4"/>
        <TvDe name="iPhone5"/>
    </Brand>
</PhoneInfo>

添加品牌为三星,型号为note20的手机。
代码展示:

import org.w3c.dom.*;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class TestXML {
    Document document;

    public void setDocument(String xmlPath) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            document = builder.parse(xmlPath);
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
//        Document document;
//        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//        DocumentBuilder builder = factory.newDocumentBuilder();
//        document = builder.parse("D:/shuju/20200807-XML/src/phone_info.xml");
        TestXML xml = new TestXML();
        xml.setDocument("D:/shuju/20200807-XML/src/phone_info.xml");
        NodeList brands = xml.document.getElementsByTagName("brand");
        //NodeList brands = document.getElementsByTagName("brand");
        Node item = brands.item(0);
        Element e = (Element) item;
        //System.out.println(e.getAttribute("name"));
        NodeList hwTypes = e.getChildNodes();
        //建节点,追加到节点上
        Node root = xml.document.getElementsByTagName("phoneInfo").item(0);
        Element sx = xml.document.createElement("brand");
        sx.setAttribute("name", "三星");
        Element sxType = xml.document.createElement("type");
        sxType.setAttribute("name", "note20");
        sx.appendChild(sxType);
        root.appendChild(sx);
        //保存更改
        TransformerFactory tf = TransformerFactory.newInstance();
        tf.setAttribute("indent-number", 4);
        Transformer t = tf.newTransformer();
        t.setOutputProperty(OutputKeys.INDENT, "yes");//换行
        t.setOutputProperty(OutputKeys.ENCODING, "UTF-8");//标注的字符编码
        DOMSource source = new DOMSource(xml.document);
        FileOutputStream fos = new FileOutputStream("D:/shuju/20200807-XML/src/phone_info.xml");
        StreamResult sr = new StreamResult(new OutputStreamWriter(fos));//只有用writer才能增进
        t.transform(source, sr);
//        for (int i = 0; i < hwTypes.getLength(); i++) {
//            Node n = hwTypes.item(i);
//            if (n instanceof Element) {
//                Element type = (Element) n;
//               // System.out.println(type.getAttribute("name"));
//               //获取文本信息 System.out.println(type.getTextContent());
//                Node firstChild = type.getFirstChild();
//                if (firstChild instanceof Text) {
//                    Text t = (Text) firstChild;
//                    System.out.println(t.getWholeText().trim());
//                }
//            }
//        }
    }
}

输出结果:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<phoneInfo>
    <brand name="华为">
        <type>
            P30
        </type>
        <type>mate30</type>
        <type>P40pro</type>
    </brand>
    <brand name="苹果">
        <type name="iphone11p"/>
        <type name="iphongx"/>
</brand>
<brand name="三星">
        <type name="note20"/>
    </brand>
</phoneInfo>

JSON

JSON简介

JSON(JavaScript Object Notation)是JavaScript中的对象表示法。
轻量级的文本数据交换格式,独立于JavaScript语言。
具有自我描述性。
比XML传输速度快。

JSON规则

数据由名称/值对构成。
数据之间由逗号分隔。
大括号内为对象。
中括号内为数组。
在这里插入图片描述
实例四:

import java.io.Serializable;
public class Student implements Serializable {
    private  int stuId;
    private String stuName;
    private String gender;
    private double score;
    public Student(){}
    public Student(int stuId, String stuName, String gender, double score) {
        this.stuId = stuId;
        this.stuName = stuName;
        this.gender = gender;
        this.score = score;
    }

    public int getStuId() {
        return stuId;
    }

    public void setStuId(int stuId) {
        this.stuId = stuId;
    }

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "stuId=" + stuId +
                ", stuName='" + stuName + '\'' +
                ", gender='" + gender + '\'' +
                ", score=" + score +
                '}';
    }
}
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.bcel.internal.generic.JsrInstruction;
public class TestJson {
    public static void main(String[] args) {
        Student s = new Student(1, "川普", "男", 55.5);
        System.out.println(s);
        //JSON j = new JSONObject();
        String jsonString = JSON.toJSONString(s);
        System.out.println(jsonString);
        //Object o = JSON.parse(jsonString);
        JSONObject jsonObject = JSON.parseObject(jsonString);
       // Student t=JSON.toJavaObject((JSON) o, Student.class);
        Student t = JSON.toJavaObject(jsonObject, Student.class);
        System.out.println(t);

    }
}

输出结果:在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值