1.Java中操作XML常见的几种方式
1.DOM
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("{}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是基于事件驱动的,所以它提供了几个事件处理器:EntityResolver、DTDHandler、ContentHandler、ErrorHandler。我们一般常用的是ContentHandler和ErrorHandler,ContentHandler提供了解析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);
}
}
复制代码
来源:掘金推荐
