引用dom4j.jar
package com.utils;
import com.alibaba.fastjson.JSON;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class XmlUtils {
public static String DDD = "http://apache.org/xml/features/disallow-doctype-decl";
public static XmlNode convert(String xml) {
try {
return convert(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)));
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
public static XmlNode convert(InputStream in) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature(DDD, true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(in);
document.normalize();
Node root = document.getDocumentElement();
return toNode(root, null);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
/**
* 节点转对象
*
* @param node
* @param parentNode
* @return
*/
private static XmlNode toNode(Node node, XmlNode parentNode) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
List<Node> childElementNodes = getChildElementNodes(node);
if (childElementNodes.size() == 0) {
return new XmlNode(node.getNodeName(), node.getAttributes(), node.getTextContent().trim(), parentNode);
} else {
XmlNode xmlNode = new XmlNode(node.getNodeName(), node.getAttributes(), parentNode);
for (Node childElementNode : childElementNodes) {
xmlNode.addChild(toNode(childElementNode, xmlNode));
}
return xmlNode;
}
}
return null;
}
/**
* 获取所有为Element_Node的子节点
*/
private static List<Node> getChildElementNodes(Node node) {
List<Node> childElementNodes = new ArrayList<Node>();
if (node.getNodeType() == Node.ELEMENT_NODE) {
NodeList childNodes = node.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node childNode = childNodes.item(i);
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
childElementNodes.add(childNode);
}
}
}
return childElementNodes;
}
public static String format(String xml) {
if (StringUtils.isEmpty(xml)) {
return "";
}
try {
SAXReader reader = new SAXReader();
StringReader in = new StringReader(xml);
org.dom4j.Document doc = reader.read(in);
OutputFormat formater = OutputFormat.createPrettyPrint();
formater.setIndentSize(4);
formater.setEncoding("UTF-8");
StringWriter out = new StringWriter();
XMLWriter writer = new XMLWriter(out, formater);
writer.write(doc);
writer.close();
return out.toString();
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
public static class XmlNode {
private String name;
private String uri;
private List<XmlNode> attributes;
private String content;
private XmlNode parent;
private List<XmlNode> children;
public XmlNode() {
}
/**
* attribute node
*/
public XmlNode(String name, String content, XmlNode parent) {
this.name = name;
this.uri = (parent != null ? parent.getUri() : "") + "[" + name + "]";
this.content = content;
this.parent = parent;
}
/**
* node with children
*/
public XmlNode(String name, NamedNodeMap attributes, XmlNode parent) {
this.name = name;
this.uri = (parent != null ? parent.getUri() : "") + "/" + name;
this.parent = parent;
setAttributes(attributes);
}
/**
* node without children
*/
public XmlNode(String name, NamedNodeMap attributes, String content, XmlNode parent) {
this.name = name;
this.uri = (parent != null ? parent.getUri() : "") + "/" + name;
this.content = content;
this.parent = parent;
setAttributes(attributes);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public List<XmlNode> getAttributes() {
return attributes;
}
public void setAttributes(NamedNodeMap attributes) {
if (attributes.getLength() > 0) {
if (this.attributes == null) {
this.attributes = new ArrayList<>();
}
for (int i = 0; i < attributes.getLength(); i++) {
Node attribute = attributes.item(i);
this.attributes.add(new XmlNode(attribute.getNodeName(), attribute.getNodeValue(), this));
}
}
}
public void setAttributes(List<XmlNode> attributes) {
this.attributes = attributes;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public XmlNode getParent() {
return parent;
}
public void setParent(XmlNode parent) {
this.parent = parent;
}
public List<XmlNode> getChildren() {
return children;
}
public void setChildren(List<XmlNode> children) {
this.children = children;
}
public void addChild(XmlNode child) {
if (this.children == null) {
this.children = new ArrayList<>();
}
this.children.add(child);
}
private XmlNode getByName(String name) {
if (this.children != null) {
for (XmlNode child : this.children) {
if (child.getName().equals(name)) {
return child;
}
}
}
if (this.attributes != null) {
for (XmlNode attribute : this.attributes) {
if (attribute.getName().equals(name)) {
return attribute;
}
}
}
return null;
}
private String getContentByName(String name) {
XmlNode node = getByName(name);
return node != null ? node.getContent() : null;
}
public <T> T getContentByName(String name, Class<T> clazz) {
return getContentByName(name, clazz, null);
}
@SuppressWarnings("unchecked")
public <T> T getContentByName(String name, Class<T> clazz, T defaultValue) {
String value = getContentByName(name);
if (value != null) {
return clazz == String.class ? ((T) value) : JSON.parseObject(value, clazz);
}
return defaultValue;
}
private List<XmlNode> findByName(String name) {
List<XmlNode> nodes = new ArrayList<XmlNode>();
if (this.children != null) {
for (XmlNode node : this.children) {
if (node.getName().equals(name)) {
nodes.add(node);
}
}
}
return nodes;
}
public XmlNode getByPath(String path) {
List<String> nodeNames = CollectionUtils.split(path, "\\/");
int i = 0;
XmlNode node = this;
while (i < nodeNames.size()) {
node = node.getByName(nodeNames.get(i++));
if (node == null) {
return null;
}
}
return node;
}
public String getContentByPath(String path) {
XmlNode node = getByPath(path);
return node != null ? node.getContent() : null;
}
public <T> T getContentByPath(String path, Class<T> clazz) {
return getContentByPath(path, clazz, null);
}
@SuppressWarnings("unchecked")
public <T> T getContentByPath(String path, Class<T> clazz, T defaultValue) {
String value = getContentByPath(path);
if (value != null) {
return clazz == String.class ? ((T) value) : JSON.parseObject(value, clazz);
}
return defaultValue;
}
public List<XmlNode> findByPath(String path) {
List<String> nodeNames = CollectionUtils.split(path, "\\/");
int i = 0;
XmlNode node = this;
while (i < (nodeNames.size() - 1)) {
node = node.getByName(nodeNames.get(i++));
if (node == null) {
return new ArrayList<>();
}
}
return node.findByName(nodeNames.get(i));
}
public List<String> findContentByPath(String path) {
List<String> contentList = new ArrayList<String>();
List<XmlNode> nodes = findByPath(path);
if (nodes != null) {
for (XmlNode node : nodes) {
if (node.getContent() != null && node.getContent().length() > 0) {
contentList.add(node.getContent());
}
}
}
return contentList;
}
@SuppressWarnings("unchecked")
public <T> List<T> findContentByPath(String path, Class<T> clazz) {
List<String> list = findContentByPath(path);
if (list != null) {
return list.stream().map(o -> ((clazz == String.class) ? ((T) o) : JSON.parseObject(o, clazz))).collect(Collectors.toList());
}
return null;
}
}
}