Java对XML、JSON的操作

Java对XML、JSON的操作

XML

XML简介
  • XML:可扩展标记语言
  • 纯文本表示,跨系统/平台/语言
  • 严格区分大小写
XML组成元素

1、文档声明

2、元素=标签

3、属性

4、注释

5、CDATA区、特殊字符<!CDATA[不想解析的内容]>

文档声明 文档中必须要有一个根标签

<?xml version="1.0" encoding="UTF-8"?>

元素=标签

注:xml必须要有根节点,且只能有一个节点

<student></student>

属性

<student name='xiaoming'></student>

注释

<!--注释-->

CDATA区、特殊字符

<	&lt;
>	&gt;
"	&quot;
'	&apos;

XML Schema(XSD,XML Schema Definition)

  • 定义xml文档的结构,DTD(Document Type Definition)的继任者
  • 支持数据类型,可扩展,功能更完善、强大

XSL

  • 扩展样式表语言(eXtensible Stylesheet Language)
  • XSL作用于XML,等同于CSS作用于HTML
XML解析
XML解析方法
  • 树结构
    • DOM:Document Object Model文档对象模型,擅长(小规模)读/写
  • 流结构
    • SAX:Simple API for XML 流机制解释器(推模式),擅长读
    • Stax:The Streaming API for XML 流机制解释器(拉模式),擅长读

DOM

  • DocumentBuilder解析类,parse方法
  • Node节点主接口,getChildNodes返回一个NodeList
  • NodeList节点列表,每个元素是一个Node
    • 注意:标签和标签之间的空格也会被上级父节点视为子元素
  • Document文档根节点
  • Element标签节点元素(每一个标签都是标签节点)
  • Text节点(包含在XML元素内的,都算Text节点)
  • Attr节点(每个属性节点)

eg:

DOMReader:

//自上而下进行访问
public static void RecursiveTraverse() {
    try {
        //采用DOM解析XML文件
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db=dbf.newDocumentBuilder();
        Document document= db.parse("users.xml");

        //获取所有的一级子节点
        NodeList usersList=document.getChildNodes();
        System.out.println("usersList.getLength() = " + usersList.getLength()); //1
        for (int i = 0; i < usersList.getLength(); i++) {
            Node users=usersList.item(i);    //1 users
            NodeList userList=users.getChildNodes();//获取二级子节点user的列表
            System.out.println("userList.getLength() = " + userList.getLength());//9
            for (int j = 0; j < userList.getLength(); j++) {
                Node user=userList.item(j);
                if (user.getNodeType()==Node.ELEMENT_NODE){
                    NodeList metaList=user.getChildNodes();
                    System.out.println("metaList.getLength() = " + metaList.getLength());//7

                    for (int k = 0; k < metaList.getLength(); k++) {
                        //到最后一级文本
                        Node meta=metaList.item(k);
                        if (meta.getNodeType()==Node.ELEMENT_NODE){
                            System.out.println("metaList.item(k).getTextContent() = " + metaList.item(k).getTextContent());
                        }
                    }
                }
            }
        }
        System.out.println();
    } catch (ParserConfigurationException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (SAXException e) {
        e.printStackTrace();
    }
}

//根据名字进行搜索
public static void TraverseBySearch() {
    try {
        //采用DOM解析XML文件
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document document = db.parse("users.xml");

        Element rootElement = document.getDocumentElement();
        NodeList nodeList = rootElement.getElementsByTagName("name");
        if (nodeList != null) {
            for (int i = 0; i < nodeList.getLength(); i++) {
                Element element = (Element) nodeList.item(i);
                System.out.println("element.getTextContent() = " + element.getTextContent());
            }
        }
    } catch (ParserConfigurationException e) {
        e.printStackTrace();
    } catch (SAXException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

DOMWriter

public static void main(String[] args) {
    try {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();

        //新创建一个Document节点
        Document document = builder.newDocument();
        if (document != null) {
            Element docx = document.createElement("document");
            Element element = document.createElement("element");
            element.setAttribute("type", "para");
            element.setAttribute("alignment", "left");//element增加2个属性
            Element object = document.createElement("object");
            object.setAttribute("type", "text");

            Element text = document.createElement("text");
            text.appendChild(document.createTextNode("abcdefg"));//给text节点赋值
            Element bold = document.createElement("bold");
            bold.appendChild(document.createTextNode("true"));//给bold节点赋值

            object.appendChild(text);   //把text节点挂在object下
            object.appendChild(bold);   //把bold节点挂在object下
            element.appendChild(object);
            docx.appendChild(element);
            document.appendChild(docx); //把docx挂在document下

            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(document);

            //定义目标文件
            File file = new File("dom_result.xml");
            StreamResult result = new StreamResult(file);

            //将xml文件写入到文件中
            transformer.transform(source,result);
            System.out.println("Write xml file successfully");
        }
    } catch (ParserConfigurationException | TransformerConfigurationException e) {
        e.printStackTrace();
    } catch (TransformerException e) {
        e.printStackTrace();
    }
}

SAX(Simple API for XML)

  • 采用事件/流模型来解析XML文档,更快速、更轻量
  • 有选择的解析和访问,不像DOM加载整个文档,内存要求更低
  • SAX对XML文档的解析为一次性读取,不创建/不存储文档对象,很难同时访问文档中的多处数据
  • 推模型。当它每发现一个节点就引发一个事件,而我们需要编写这些事件的处理程序。关键类:DefaultHandler
  • SAX的5个回调方法
    • startDocument 文档开始解析
    • endDocument 文档结束解析
    • startElement 开始访问元素
    • endElement 结束访问元素
    • characters 访问元素正文
public class SAXReader {
    public static void main(String[] args) throws SAXException, IOException {
        XMLReader parser = XMLReaderFactory.createXMLReader();
        BoolHandler boolHandler = new BoolHandler();
        parser.setContentHandler(boolHandler);
        parser.parse("books.xml");
        System.out.println("boolHandler = " + boolHandler.getNameList());
    }
}

class BoolHandler extends DefaultHandler {
    private List<String> nameList;
    private boolean title = false;

    public List<String> getNameList() {
        return nameList;
    }

    //实现DefaultHandler的5个回调方法

    //xml文档加载时
    public void startDocument() throws SAXException {
        System.out.println("Start parsing document...");
        nameList = new ArrayList<String>();
    }

    //文档解析结束
    public void endDocument() throws SAXException {
        System.out.println("End");
    }

    //访问某一个元素
    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
        if (qName.equals("title"))
            title = true;
    }

    //结束访问元素
    public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
        //End of processing current element
        if (title) {
            title = false;
        }
    }

    //访问元素正文
    public void characters(char[] ch, int start, int length) {
        if (title) {
            String bookTitle = new String(ch, start, length);
            System.out.println("bookTitle = " + bookTitle);
            nameList.add(bookTitle);
        }
    }
}

Stax(Streaming API for XML)

  • 流模型中的拉模型
  • 在遍历文档时,会把感兴趣的部分从读取器中拉出,不需要引发事件,允许我们选择性地处理节点。这大大提高了灵活性,以及整体效率。
  • 两套处理API
    • 基于指针的API,XMLStreamReader
    • 基于迭代器的API,XMLEventReader

eg:

//流模式
public static void readByStream() {
    String xmlFile = "books.xml";
    XMLInputFactory factory = XMLInputFactory.newFactory();
    XMLStreamReader streamReader = null;
    try {
        streamReader = factory.createXMLStreamReader(new FileReader(xmlFile));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (XMLStreamException e) {
        e.printStackTrace();
    }

    //基于指针遍历
    try {
        while (streamReader.hasNext()) {
            int event = streamReader.next();
            //如果是元素的开始
            if (event == XMLStreamConstants.START_ELEMENT) {
                //列出所有书籍名称
                if ("title".equalsIgnoreCase(streamReader.getLocalName())) {
                    System.out.println("title: " + streamReader.getElementText());
                }
            }
        }
        streamReader.close();
    } catch (XMLStreamException e) {
        e.printStackTrace();
    }

}

//事件模式
public static void readByEvent() {
    String xmlFile = "books.xml";
    XMLInputFactory factory = XMLInputFactory.newFactory();
    boolean titleFlag = false;
    try {
        //创建基于迭代器的事件读取器对象
        XMLEventReader eventReader = factory.createXMLEventReader(new FileReader(xmlFile));
        //遍历Event迭代器
        while (eventReader.hasNext()) {
            XMLEvent event = eventReader.nextEvent();
            //如果事件对象是元素的开始
            if (event.isStartElement()) {
                //转换成开始元素事件对象
                StartElement start = event.asStartElement();
                //打印元素标签的本地名称
                String name = start.getName().getLocalPart();
                if (name.equals("title")) {
                    titleFlag = true;
                    System.out.println("title:");
                }
                //取得所有属性
                Iterator attrs = start.getAttributes();
                while (attrs.hasNext()) {
                    //打印所有属性信息
                    Attribute attr = (Attribute) attrs.next();
                    //System.out.println("attr.getValue() = " + attr.getValue());
                }
                //如果是正文
                if (event.isCharacters()) {
                    String s = event.asCharacters().getData();
                    if (null != s && s.trim().length() > 0 && titleFlag) {
                        System.out.println("s.trim() = " + s.trim());
                    }
                }
                //如果事件对象是元素的结束
                if (event.isEndElement()) {
                    EndElement end = event.asEndElement();
                    String titleName = end.getName().getLocalPart();
                    if (titleName.equals("title")) {
                        titleFlag = false;
                    }
                }
            }
            eventReader.close();
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (XMLStreamException e) {
        e.printStackTrace();
    }

}

JSON

JSON简介
  • JavaScript Object Notation,js对象表示法

  • 一种轻量级的数据交换格式

  • JSONObject,名称-值对。如"firstName":“John”

    • json对象:{“name”:“John”,“email”:“a@b.com”}
    • 数据在键值对中
    • 数据由逗号分隔
    • 花括号保存对象
  • JSONArray,json数组

    • 方括号保存数组
      • [{K:V,K:V,K:V,…},{}]
java的JSON处理

jdk本身没有JSON的处理包,故而只能通过在Maven repository中添加工具包来处理

  • org.json:JSON官方推荐的解析类
    • 简单易用,通用性强,但无法完成复杂功能
  • GSON:Google出品。基于反射,可以实现JSON对象、JSON字符串和Java对象互转
  • Jackson:号称最快的JSON处理器
JSON主要用途
  • JSON生成
  • JSON解析
  • JSON校验
  • Java Bean对象进行互解析
    • 具有一个无参的构造函数
    • 可以包括多个属性,所有属性都是private
    • 每个属性都有相应的Getter/Settrt方法
    • Java Bean用于封装数据,又可称为POJO(Plain Old Java Object)

eg:

Person.java Java Bean类

public class Person {
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public List<Integer> getScores() {
        return scores;
    }
    public void setScores(List<Integer> scores) {
        this.scores = scores;
    }
    private String name;
    private int age;
    private List<Integer> scores;
    public Person() {

    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

books.json

{
  "books": [
    {
      "category": "COOKING",
      "title": "Everyday Italian",
      "author": "Giada De Laurentiis",
      "year": "2005",
      "price": 30.00
    },
    {
      "category": "CHILDREN",
      "title": "Harry Potter",
      "author": "J K. Rowling",
      "year": "2005",
      "price": 29.99
    },
    {
      "category": "WEB",
      "title": "Learning XML",
      "author": "Erik T. Ray",
      "year": "2003",
      "price": 39.95
    }
  ]
}
org.json:

pom.xml中添加依赖

<!--org.json Java官方推荐的JSON处理包-->
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
  <version>20180813</version>
</dependency>
 //写JSON文件
public static void testJsonObject() {
    //构造对象
    Person p = new Person();
    p.setName("Tom");
    p.setAge(20);
    p.setScores(Arrays.asList(60,70,80));


    //构造JSONObject对象
    JSONObject obj = new JSONObject();

    //string
    obj.put("name", p.getName());
    //int
    obj.put("age", p.getAge());
    //array
    obj.put("scores", p.getScores());
    //null
    //object.put("null", null);
    System.out.println(obj);

    System.out.println("name: " + obj.getString("name"));
    System.out.println("age: " + obj.getInt("age"));
    System.out.println("scores: " + obj.getJSONArray("scores"));
}

//读JSON文件
public static void testJsonFile() {
    File file = new File("books.json");
    try (FileReader reader = new FileReader(file)) {
        //读取文件内容到JsonObject对象中
        int fileLen = (int) file.length();
        char[] chars = new char[fileLen];
        reader.read(chars);
        String s = String.valueOf(chars);
        JSONObject jsonObject = new JSONObject(s);

        //开始解析JSONObject对象
        JSONArray books = jsonObject.getJSONArray("books");
        List<ArrayList> bookList = new ArrayList<>();
        for (Object book : books) {
            //获取单个JSONObject对象
            JSONObject bookObject = (JSONObject) book;
            ArrayList book1=new ArrayList();
            book1.add(bookObject.getString("author"));
            book1.add(bookObject.getString("year"));
            book1.add(bookObject.getString("title"));
            book1.add(bookObject.getInt("price"));
            book1.add(bookObject.getString("category"));
            bookList.add(book1);
        }
        for (ArrayList book : bookList) {
            System.out.println(book.get(0)+","+book.get(2));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
GSON:(从代码上看,GSON功能更强大,使用更方便,推荐使用GSON解析JSON)

pom.xml中添加依赖

<!--GSON处理JSON包,基于反射,可以实现JSON对象、JSON字符串和Java对象互转-->
<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.7</version>
</dependency>
public static void testJsonObject() {
    //构造对象
    Person p = new Person();
    p.setName("Tom");
    p.setAge(20);
    p.setScores(Arrays.asList(60,70,80));

    //从Java对象到JSON字符串
    Gson gson = new Gson();
    String s = gson.toJson(p);
    System.out.println(s); //{"name":"Tom","age":20,"scores":[60,70,80]}

    //从JSON字符串到Java对象
    Person p2 = gson.fromJson(s, Person.class);
    System.out.println(p2.getName());  //Tom
    System.out.println(p2.getAge());   //20
    System.out.println(p2.getScores());//[60, 70, 80]

    //调用GSON的JsonObject
    JsonObject json = gson.toJsonTree(p).getAsJsonObject(); //将整个json解析为一颗树
    System.out.println(json.get("name"));  //"Tom"
    System.out.println(json.get("age"));   //20
    System.out.println(json.get("scores"));//[60,70,80]

}

public static void testJsonFile() {
    Gson gson = new Gson();
    File file = new File("books2.json");

    try (FileReader reader = new FileReader(file)) {
        //从JSON字符串到Java对象
        List<Book> books = gson.fromJson(reader, new TypeToken<List<Book>>(){}.getType());
    } catch (Exception e) {
        e.printStackTrace();
    }
}
XML与JSON的比较
  • 都是数据交换格式,可读性强,可扩展性高
  • 大部分的情况下,JSON更具优势(编码简单,转换方便),而且JSON字符长度一般小于XML,传输效率更高
  • XML更加注重标签和顺序,JSON会丢失信息
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值