Java 操作 XML(15)--XOM 使用

发布时间 2023-11-05 20:36:07作者: 且行且码

XOM 是一个面向对象的 XML API,有点像 DOM 风格,但是许多功能使XOM与众不同,其中最主要的是严格维护内存对象中的不变性,以便始终可以将 XOM 实例序列化以更正 XML。本文主要介绍使用 XOM 处理 XML,文中所使用到的软件版本:Java 1.8.0_341、XOM 1.3.9。

1、简介

XOM 被设计成易于学习和使用。它的工作方式非常直观,学习曲线非常平缓。如果您已经熟悉 XML,应该能够很快地开始使用 XOM。

XOM 是唯一一款在正确性方面不妥协的 XML API。XOM 只接受命名空间格式良好的 XML 文档,并且只允许您创建命名空间格式良好的 XML 文档。(事实上,它比这还要严格:它实际上保证所有文档都是可相互转换的,具有明确定义的 XML 信息集。)XOM 会管理您的 XML,使您无需费心。有了 XOM,您可以专注于应用程序的独特价值,并信任 XOM 正确处理 XML。

XOM 在两个关键方面相当独特,它是一个同时支持流式处理和树结构的 API。在构建文档时,可以同时处理树中的各个节点。这使得 XOM 程序几乎可以与底层解析器提供数据的速度相匹配。您无需等待文档完全解析后才能开始使用它。

XOM 非常高效地利用内存。如果将整个文档读入内存,XOM 会尽可能地节省内存。更重要的是,XOM 允许在文档构建过程中进行过滤,因此您无需构建不感兴趣的树部分。例如,如果在应用程序中表示边界的空白文本节点不重要,可以跳过构建它们。甚至可以逐段处理文档,并在处理完每个段后将其丢弃。XOM 已用于处理占用几个 GB 的文档。

2、使用 XOM 处理 XML

2.1、XML 文件

<?xml version="1.0" encoding="utf-8" ?>
<school:grade xmlns:school="http://www.w3.org/TR/html4/school/">
    <school:student rollno="1" school:age="10">
        <school:firstname>cxx1</school:firstname>
        <lastname>Bob1</lastname>
        <nickname>stars1</nickname>
        <marks>85</marks>
    </school:student>
    <student rollno="2">
        <school:firstname>cxx2</school:firstname>
        <lastname>Bob2</lastname>
        <nickname>stars2</nickname>
        <marks>85</marks>
    </student>
    <student rollno="3">
        <school:firstname>cxx3</school:firstname>
        <lastname>Bob3</lastname>
        <nickname>stars3</nickname>
        <marks>85</marks>
    </student>
</school:grade>

2.2、引入依赖

<dependency>
    <groupId>xom</groupId>
    <artifactId>xom</artifactId>
    <version>1.3.9</version>
</dependency>

2.3、使用例子

该例子演示了使用 XOM 解析 XML、XOM 中 XPath 的使用以及使用 XOM 来生成 XML。

package com.abc.demo.ws;

import lombok.extern.slf4j.Slf4j;
import nu.xom.*;
import org.junit.Test;


@Slf4j
public class XomCase {
    @Test
    public void parse() throws Exception {
        String namespace = "http://www.w3.org/TR/html4/school/";
        Builder builder = new Builder(false);
        Document document = builder.build(XomCase.class.getClassLoader().getResourceAsStream("student.xml"));
        Element root = document.getRootElement();
        Elements elements = root.getChildElements();
        for (Element student : elements) {
            String rollno = student.getAttributeValue("rollno");
            Attribute ageAttribute = student.getAttribute("age", namespace);
            String age = null;
            if (ageAttribute != null) {
                age = ageAttribute.getValue();
            }
            String firstname = student.getFirstChildElement("firstname", namespace).getValue();
            String lastname = student.getFirstChildElement("lastname").getValue();
            String nickname = student.getFirstChildElement("nickname").getValue();
            String marks = student.getFirstChildElement("marks").getValue();
            log.info("rollno={},age={},firstname={},lastname={},nickname={},marks={}", rollno, age, firstname, lastname, nickname, marks);
        }
    }

    @Test
    public void xpath() throws Exception {
        String namespace = "http://www.w3.org/TR/html4/school/";
        Builder builder = new Builder(false);
        Document document = builder.build(XomCase.class.getClassLoader().getResourceAsStream("student.xml"));
        log.info("查找存在rollno属性的student节点,找到的节点再查找lastname子节点,找到的节点再查找文本节点");
        Nodes nodes = document.query("//student[@rollno]/lastname/text()");//第二、三位学生
        //Nodes nodes = document.query("//student[@rollno]/child::lastname/text()");//效果同上
        for (Node node : nodes) {
            log.info(node.getValue());
        }

        log.info("查找存在rollno属性的school:student节点,找到的节点再查找school:firstname子节点");
        XPathContext xPathContext = new XPathContext("school", namespace);
        nodes = document.query("//school:student/school:firstname", xPathContext);//第一位学生
        for (Node node : nodes) {
            log.info(node.getValue());
        }
    }

    @Test
    public void toXml() throws Exception {
        String namespace = "http://www.w3.org/TR/html4/school/";
        Element root = new Element("school:grade", namespace);
        //第一个student
        Element student = new Element("school:student", namespace);
        student.addAttribute(new Attribute("rollno", "1"));
        student.addAttribute(new Attribute("school:age", namespace, "10"));
        Element firstname = new Element("school:firstname", namespace);
        firstname.appendChild("cxx1");
        student.appendChild(firstname);
        Element lastname = new Element("lastname");
        lastname.appendChild("Bob1");
        student.appendChild(lastname);
        Element nickname = new Element("nickname");
        nickname.appendChild("stars1");
        student.appendChild(nickname);
        Element marks = new Element("marks");
        marks.appendChild("85");
        student.appendChild(marks);
        root.appendChild(student);

        //第二个student
        Element student2 = new Element("school:student", namespace);
        student2.addAttribute(new Attribute("rollno", "2"));
        Element firstname2 = new Element("school:firstname", namespace);
        firstname2.appendChild("cxx2");
        student2.appendChild(firstname2);
        Element lastname2 = new Element("lastname");
        lastname2.appendChild("Bob2");
        student2.appendChild(lastname2);
        Element nickname2 = new Element("nickname");
        nickname2.appendChild("stars2");
        student.appendChild(nickname2);
        Element marks2 = new Element("marks");
        marks2.appendChild("85");
        student2.appendChild(marks2);
        root.appendChild(student2);

        //第三个student
        Element student3 = new Element("school:student", namespace);
        student3.addAttribute(new Attribute("rollno", "3"));
        Element firstname3 = new Element("school:firstname", namespace);
        firstname3.appendChild("cxx3");
        student3.appendChild(firstname3);
        Element lastname3 = new Element("lastname");
        lastname3.appendChild("Bob3");
        student3.appendChild(lastname3);
        Element nickname3 = new Element("nickname");
        nickname3.appendChild("stars3");
        student3.appendChild(nickname3);
        Element marks3 = new Element("marks");
        marks3.appendChild("85");
        student3.appendChild(marks3);
        root.appendChild(student3);

        Document document = new Document(root);
        log.info(document.toXML());
        //序列化,可以设置输出格式
        Serializer serializer = new Serializer(System.out,"UTF-8");
        //缩进空格数
        serializer.setIndent(4);
        //每行最大宽度
        serializer.setMaxLength(60);
        serializer.write(document);
        serializer.flush();
    }
}

 

 

参考:
https://github.com/elharo/xom/
https://xom.nu/tutorial.xhtml