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(); } } 复制代码
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
是基于事件驱动的,所以它提供了几个事件处理器: EntityResolver
、 DTDHandler
、 ContentHandler
、 ErrorHandler
。我们一般常用的是 ContentHandler
和 ErrorHandler
, ContentHandler
提供了解析XML时回调的方法, ErrorHandler
提供了解析出现异常时的处理方法。 DefaultHandler
实现了这四个处理器,但真正的进行处理,类似于模板方法模式,交给子类来实现,因此我们一般会自定一个 Handler
实现我们需要的方法即可。
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(); } } 复制代码
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); } } 复制代码