转载

Java中操作XML的几种方式

DOM(Document Object Model)文档对象模型是JAXP(Java API for XML Program)的一部分。Java DOM解析器负责解析XML文件并创建相应的DOM对象,这些DOM对象以树结构链接在一起。解析器将整个XML结构读入内存。

preson.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?><person>
    <p1>
        <name>张三</name>
        <age>20</age>
        <sex>man</sex><sex>man</sex></p1>
    <p1>
        <name>李四</name>
        <age>30</age>
    </p1>
</person>
复制代码

continents.xml

<?xml version="1.0" encoding="UTF-8"?>
<continents>
    <europe>
        <slovakia>
            <capital>
                Bratislava
            </capital>
            <population>
                421000
            </population>
        </slovakia>
        <hungary>
            <capital>
                Budapest
            </capital>
            <population>
                1759000
            </population>
        </hungary>
        <poland>
            <capital>
                Warsaw
            </capital>
            <population>
                1735000
            </population>
        </poland>
    </europe>
    <asia>
        <china>
            <capital>
                Beijing
            </capital>
            <population>
                21700000
            </population>
        </china>

        <vietnam>
            <capital>
                Hanoi
            </capital>
            <population>
                7500000
            </population>
        </vietnam>
    </asia>
</continents>
复制代码

DOM

public class TestDOM {
    public static void selectAll() throws ParserConfigurationException, IOException, SAXException {
        System.out.println("-----------------------------------------------------");

        //1.创建解析器工厂
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        //2.根据解析器工厂创建解析器
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        //3.根据xml文件生成Document
        Document document = documentBuilder.parse("src//main//java//com//ly//jaxp//person.xml");
        NodeList nodeList = document.getElementsByTagName("name");
        for (int n = 0; n < nodeList.getLength(); n++) {
            Node node = nodeList.item(n);
            String textContent = node.getTextContent();
            System.out.println(textContent);
        }
    }

    public static void selectOne() throws ParserConfigurationException, IOException, SAXException {
        System.out.println("-----------------------------------------------------");
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document document = documentBuilder.parse("src//main//java//com//ly//jaxp//person.xml");
        NodeList nodeList = document.getElementsByTagName("name");
        Node node = nodeList.item(0);
        String textContent = node.getTextContent();
        System.out.println(textContent);
    }

    public static void addNode() throws ParserConfigurationException, IOException, SAXException, TransformerException {
        System.out.println("-----------------------------------------------------");

        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document document = documentBuilder.parse("src//main//java//com//ly//jaxp//person.xml");
        NodeList nodeList = document.getElementsByTagName("p1");
        Node node = nodeList.item(0);
        //1.创建标签
        Element element = document.createElement("sex");
        //2.创建标签中的内容
        Text text = document.createTextNode("man");
        //3.标签追加内容
        element.appendChild(text);
        //4.节点追加标签
        node.appendChild(element);

        //5.进行回写,xslt
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.transform(new DOMSource(document), new StreamResult("src//main//java//com//ly//jaxp//person.xml"));
    }

    public static void updateNode() throws ParserConfigurationException, IOException, SAXException, TransformerException {
        System.out.println("-----------------------------------------------------");

        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document document = documentBuilder.parse("src//main//java//com//ly//jaxp//person.xml");
        NodeList nodeList = document.getElementsByTagName("sex");
        Node node = nodeList.item(0);
        //1.更改节点内容
        node.setTextContent("woman");

        //2.进行回写
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.transform(new DOMSource(document), new StreamResult("src//main//java//com//ly//jaxp//person.xml"));
    }

    public static void deleteNode() throws ParserConfigurationException, IOException, SAXException, TransformerException {
        System.out.println("-----------------------------------------------------");
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document document = documentBuilder.parse("src//main//java//com//ly//jaxp//person.xml");
        NodeList nodeList = document.getElementsByTagName("sex");
        Node node = nodeList.item(0);
        //1.拿到要删除节点的父节点,根据父节点删除子节点
        Node parentNode = node.getParentNode();
        parentNode.removeChild(node);

        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.transform(new DOMSource(document), new StreamResult("src//main//java//com//ly//jaxp//person.xml"));
    }

    public static void listElement() throws ParserConfigurationException, IOException, SAXException {
        System.out.println("-----------------------------------------------------");

        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document document = documentBuilder.parse("src//main//java//com//ly//jaxp//person.xml");
        list1(document);
    }

    private static void list1(Node node) {
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            System.out.println(node.getNodeName());
        }
        NodeList childNodes = node.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node item = childNodes.item(i);
            list1(item);
        }
    }

    public static void iterator() throws ParserConfigurationException, IOException, SAXException {
        File file = new File("src//main//java//com//ly//jaxp//user.xml");
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document document = documentBuilder.parse(file);

        //1.规范化
        document.getDocumentElement().normalize();
        //2.强转为DocumentTraversal对象
        DocumentTraversal documentTraversal = (DocumentTraversal) document;
        //3.获取迭代器
        NodeIterator nodeIterator = documentTraversal.createNodeIterator(document.getDocumentElement(), NodeFilter.SHOW_ELEMENT, null, true);
        for (Node node = nodeIterator.nextNode(); node != null; node = nodeIterator.nextNode()) {
            String nodeName = node.getNodeName();
            System.out.println(nodeName);
        }

        System.out.println("-----------------------------------------------------");
        NodeIterator textNodeIterator = documentTraversal.createNodeIterator(document.getDocumentElement(), NodeFilter.SHOW_TEXT, null, true);
        for (Node node = textNodeIterator.nextNode(); node != null; node = textNodeIterator.nextNode()) {
            String textContent = node.getTextContent().trim();
            System.out.println(textContent);
        }
    }

    public static void iteratorCustomizeFilter() throws IOException, SAXException, ParserConfigurationException {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document document = documentBuilder.parse("src//main//java//com//ly//jaxp//continents.xml");

        document.getDocumentElement().normalize();
        DocumentTraversal documentTraversal = (DocumentTraversal) document;

        MyFilter myFilter = new MyFilter();
        NodeIterator nodeIterator = documentTraversal.createNodeIterator(document.getDocumentElement(), NodeFilter.SHOW_ELEMENT, myFilter, true);
        for (Node node = nodeIterator.nextNode(); node != null; node = nodeIterator.nextNode()) {
            String nodeName = node.getNodeName();
            String textContent = node.getTextContent();
            System.out.println(nodeName + ":" + textContent);
        }
    }

    static class MyFilter implements NodeFilter {

        @Override
        public short acceptNode(Node n) {
            if (n.getNodeType() == Node.ELEMENT_NODE) {
                String nodeName = n.getNodeName();
                if (Objects.equals("slovakia", nodeName) || Objects.equals("poland", nodeName)) {
                    return NodeFilter.FILTER_ACCEPT;
                }
            }
            return NodeFilter.FILTER_REJECT;
        }
    }

    public static void treeWalker() throws ParserConfigurationException, IOException, SAXException {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document document = documentBuilder.parse("src//main//java//com//ly//jaxp//continents.xml");
        document.getDocumentElement().normalize();

        DocumentTraversal documentTraversal = (DocumentTraversal) document;
        TreeWalker treeWalker = documentTraversal.createTreeWalker(document.getDocumentElement(), NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, null, true);
        treeWalkerRecursion(treeWalker);
    }

    private static void treeWalkerRecursion(TreeWalker walker) {
        Node currentNode = walker.getCurrentNode();
        if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
            System.out.println(currentNode.getNodeName());
        }
        if (currentNode.getNodeType() == Node.TEXT_NODE) {
            System.out.println(currentNode.getTextContent());
        }
        //深度递归
        for (Node n = walker.firstChild(); n != null; n = walker.nextSibling()) {
            treeWalkerRecursion(walker);
        }
        //回溯
        walker.setCurrentNode(currentNode);
    }

    public static void createXML() throws ParserConfigurationException, TransformerException {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document document = documentBuilder.newDocument();
        Element rootElement = document.createElementNS("zetcode.com", "users");
        document.appendChild(rootElement);

        rootElement.appendChild(createUser(document, "1", "Robert", "Brown", "programer"));
        rootElement.appendChild(createUser(document, "2", "Pamela", "Kyle", "writer"));
        rootElement.appendChild(createUser(document, "3", "Peter", "Smith", "teacher"));


        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        //编码
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        //这两个设置表示缩进
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

        DOMSource domSource = new DOMSource(document);

        File file = new File("src//main//java//com//ly//jaxp//create.xml");
        StreamResult fileResult = new StreamResult(file);

        StreamResult consoleResult = new StreamResult(System.out);

        transformer.transform(domSource, fileResult);
        transformer.transform(domSource, consoleResult);
    }

    private static Node createUser(Document document, String id, String firstName, String lastName, String occupation) {
        Element element = document.createElement("user");
        element.setAttribute("id", id);
        element.appendChild(createUserElement(document, "firstName", firstName));
        element.appendChild(createUserElement(document, "lastName", lastName));
        element.appendChild(createUserElement(document, "occupation", occupation));
        return element;
    }

    private static Node createUserElement(Document document, String name, String value) {
        Element element = document.createElement(name);
        element.appendChild(document.createTextNode(value));
        return element;
    }

    public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException, TransformerException {
        //        selectAll();
        //        selectOne();
        //        addNode();
        //        updateNode();
        //        deleteNode();
        //        listElement();
        //        traversal();
        //        iteratorCustomizeFilter();
        //        treeWalker();
        //        createXML();
    }
}
复制代码

2.SAX

SAX(Simple API for XML)是DOM的替代方法,基于事件驱动解析XML。 SAX只读

SAX

public class TestSAX {
    private SAXParser createInstance() {
        SAXParser parser = null;
        try {
            SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
            parser = saxParserFactory.newSAXParser();
        } catch (ParserConfigurationException | SAXException e) {
            e.printStackTrace();
        }
        return parser;
    }

    private List<User> parseUserList() {
        MyHandler myHandler = new MyHandler();
        try {
            File file = Paths.get("src//main//java//com//ly//jaxp//user.xml").toFile();
            SAXParser saxParser = createInstance();
            //这里会进行Handler执行
            saxParser.parse(file, myHandler);
        } catch (SAXException | IOException e) {
            e.printStackTrace();
        }
        return myHandler.getUserList();
    }

    public static void main(String[] args) {
        TestSAX testSAX = new TestSAX();
        List<User> userList = testSAX.parseUserList();
        for (User user : userList) {
            System.out.println(user.toString());
        }
    }
}
复制代码

hanlder

public class MyHandler extends DefaultHandler {
    private List<User> list = new ArrayList<>();
    private User user;

    private boolean bfn = false;
    private boolean bln = false;
    private boolean boc = false;

    //每解析一个标签的时候都会回调该方法
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if (Objects.equals("user", qName)) {
            user = new User();
            int id = Integer.parseInt(attributes.getValue("id"));
            user.setId(id);
        }

        switch (qName) {
            case "firstname":
                bfn = true;
                break;
            case "lastname":
                bln = true;
                break;
            case "occupation":
                boc = true;
                break;
            default:
                break;
        }
    }

    //每次遇到textContent的时候会回调该方法
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if (bfn) {
            user.setFirstName(new String(ch, start, length));
            bfn = false;
        }
        if (bln) {
            user.setLastName(new String(ch, start, length));
            bln = false;
        }
        if (boc) {
            user.setOccupation(new String(ch, start, length));
            boc = false;
        }
    }

    //每次遇到结束标签的时候会回调该方法
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (Objects.equals("user", qName)) {
            list.add(user);
        }
    }

    public List<User> getUserList() {
        return list;
    }
}
复制代码

因为 SAX 是基于事件驱动的,所以它提供了几个事件处理器: EntityResolverDTDHandlerContentHandlerErrorHandler 。我们一般常用的是 ContentHandlerErrorHandlerContentHandler 提供了解析XML时回调的方法, ErrorHandler 提供了解析出现异常时的处理方法。 DefaultHandler 实现了这四个处理器,但真正的进行处理,类似于模板方法模式,交给子类来实现,因此我们一般会自定一个 Handler 实现我们需要的方法即可。

3.JAXB

JAXB是可以把XML转为Java Object,也可以把Java Object转为XML,本身是由JDK提供的,在JAVA11之后需要引入jar包。

maven

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.2.11</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-core</artifactId>
    <version>2.2.11</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2.11</version>
</dependency>
<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>
复制代码

Java Object

@XmlRootElement(name = "book") //根标签
@XmlType(propOrder = {"author", "name", "publisher", "isbn"}) //排序
public class Book {
    private String name;
    private String author;
    private String publisher;
    private String isbn;

    @XmlElement(name = "title")//别名
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getPublisher() {
        return publisher;
    }

    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }

    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    @Override
    public String toString() {
        return "Book{" +
            "name='" + name + '/'' +
            ", author='" + author + '/'' +
            ", publisher='" + publisher + '/'' +
            ", isbn='" + isbn + '/'' +
            '}';
    }
}

@XmlRootElement(namespace = "com.zetcode", name = "bookStore")
public class BookStore {
    private ArrayList<Book> bookList;
    private String name;
    private String location;

    @XmlElementWrapper(name = "bookList")
    @XmlElement(name = "book")
    //    @XmlTransient
    public ArrayList<Book> getBookList() {
        return bookList;
    }

    public void setBookList(ArrayList<Book> bookList) {
        this.bookList = bookList;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    @Override
    public String toString() {
        return "BookStore{" +
            "bookList=" + bookList +
            ", name='" + name + '/'' +
            ", location='" + location + '/'' +
            '}';
    }
}
复制代码

JAXB

public class TestJAXB {
    private static final String BOOKSTORE_XML = "src//main//java//com//ly//jaxp//bookstore.xml";

    public static void toXML() throws JAXBException {
        ArrayList<Book> list = new ArrayList<>();

        Book book1 = new Book();
        book1.setIsbn("978-0060554736");
        book1.setName("The Game");
        book1.setAuthor("Neil Strauss");
        book1.setPublisher("Harpercollins");
        list.add(book1);

        Book book2 = new Book();
        book2.setIsbn("978-3832180577");
        book2.setName("Feuchtgebiete");
        book2.setAuthor("Charlotte Roche");
        book2.setPublisher("Dumont Buchverlag");
        list.add(book2);

        BookStore bookStore = new BookStore();
        bookStore.setName("Fraport Bookstore");
        bookStore.setLocation("Livres belles");
        bookStore.setBookList(list);

        JAXBContext jaxbContext = JAXBContext.newInstance(BookStore.class);
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        //        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);

        marshaller.marshal(bookStore, System.out);

        marshaller.marshal(bookStore, new File(BOOKSTORE_XML));
    }

    public static void formXML() throws JAXBException {
        JAXBContext jaxbContext = JAXBContext.newInstance(BookStore.class);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        BookStore bookStore = (BookStore) unmarshaller.unmarshal(new File(BOOKSTORE_XML));
        System.out.println(bookStore);
    }

    public static void main(String[] args) throws JAXBException {
        //1.需要自己创建JAXB
        toXML();
        formXML();
        //2.java7以后,可以直接使用静态方式
        //        JAXB.marshal();
        //        JAXB.unmarshal();
    }
}
复制代码

4.XStream

XStream是一种OXMapping技术,可以很方便的将Java Bean转为XML,反之亦然。

User

@XStreamAlias(value = "user")
public class User {
    @XStreamAlias(value = "username")
    private String userName;
    @XStreamAlias(value = "email")
    private String email;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "User{" +
            "userName='" + userName + '/'' +
            ", email='" + email + '/'' +
            '}';
    }
}
复制代码

XStream

public class TestXstream {

    public static <T> T formXML(Class<T> clazz, String xml) {
        XStream xStream = new XStream();
        //解决安全框架未启动问题
        //        XStream.setupDefaultSecurity(xStream);
        //        xStream.allowTypes(new Class[]{User.class});
        //非注解别名
        xStream.alias("user",clazz);
        //使用注解别名
        //        xStream.processAnnotations(clazz);
        T t = (T) xStream.fromXML(xml);
        return t;
    }

    public static String toXML(Class clazz, Object object) {
        XStream xStream = new XStream();
        //        XStream.setupDefaultSecurity(xStream);
        //        xStream.allowTypes(new Class[]{User.class});
        //非注解别名
        xStream.alias("user",clazz);
        //使用注解别名
        //        xStream.processAnnotations(clazz);
        String xml = xStream.toXML(object);
        return xml;
    }

    public static void main(String[] args) {
        User user = new User();
        user.setUserName("张三");
        user.setEmail("123456");
        String xml = toXML(user.getClass(), user);
        System.out.println(xml);

        User user1 = formXML(User.class, xml);
        System.out.println(user1);
    }
}
复制代码
原文  https://juejin.im/post/5ec4d8f26fb9a047dc2cb0f2
正文到此结束
Loading...