本工具类基于 W3C 的 DOM 包,也就是 org.w3c.dom
DOM 中常见类或接口
DocumentBuilderFactory
:用于创建DocumentBuilder
对象的工厂类DocumentBuilder
:用于解析 XML 文档,创建Document
对象的工具类Document
:表示整个 XML 文档,可以理解为一种特殊的节点,是所有节点的根节点Node
:代表 XML 文档中的节点,包括元素节点、属性节点、文本节点等Element
:继承自Node
,表示 XML 文档中的元素节点Attr
:继承自Node
,代表 XML 文档中的属性节点Text
:继承自Node
,代表 XML 文档中的文本节点
DOM 中节点列表(NodeList
,只读且长度固定)的常用方法
getLength()
:获取NodeList
中节点的数量item(int index)
:按照索引值获取NodeList
中指定位置的节点,返回Node
对象- 注意,
NodeList
本身没有定义添加或移除节点的方法,这部分需自己实现
DOM 中节点(Node
)的常用方法
getNodeName()
:获取节点的名称getNodeType()
:获取节点的类型,如元素、属性、文本、注释等getTextContent()
:获取当前节点的文本内容getParentNode()
:获取当前节点的父节点hasChildNodes()
:判断当前节点是否有子节点getChildNodes()
:获取当前节点的所有子节点getFirstChild()
:获取第一个子节点getLastChild()
:获取最后一个子节点getNextSibling()
:获取下一个兄弟节点getPreviousSibling()
:获取上一个兄弟节点appendChild(Node newChild)
:向元素的子节点列表末尾添加一个新的子节点removeChild(Node oldChild)
:从元素的子节点列表中删除指定的子节点replaceChild(Node newChild, Node oldChild)
:用新的子节点替换元素的指定子节点
DOM 中元素(Element
)的常用方法
getTagName()
:获取元素的标签名getAttributes()
:返回元素的属性列表hasAttribute(String name)
:检查元素是否具有指定名称的属性getAttribute(String name)
:获取元素的指定属性的值setAttribute(String name, String value)
:设置元素的指定属性值removeAttribute(String name)
:删除指定属性名的属性getElementsByTagName(String name)
:返回所有指定标签名的子元素节点列表getAttributeNode(String name)
:返回指定属性名的属性节点
DOM 中属性(Attr
)的常用方法
getName()
:获取属性的名称getValue()
:获取属性的值setValue(String value)
:设置属性的值getOwnerElement()
:获取拥有此属性的元素节点
DOM 中文本(Text
)的常用方法
getData()
:获取文本节点的内容setData(String data)
:设置文本节点的内容
以上方法笔者觉得没有必要再封装进工具类了,直接调用就行
而其他的处理可以参考笔者的 XML 处理工具类 XMLUtils
的以下方法
nodeListToList()
:将节点列表转换为元素为节点的列表listToNodeList()
:将元素为节点的列表转换为节点列表nodeToElement()
:将节点转换为元素节点nodeToAttr()
:将节点转换为属性节点nodeToText()
:将节点转换为文本节点elementToNode()
:将元素节点转换为节点attrToNode()
:将属性节点转换为节点textToNode()
:将文本节点转换为节点strToDoc()
:将 XML 字符串转换为文档对象docToStr()
:将文档对象转换为 XML 字符串getChildNodes()
:获取给定节点的所有子节点getChildElements()
:获取给定元素的所有子元素getElementAttrs()
:获取给定元素的所有属性readXMLFile()
:读取 XML 文件并返回文档对象printXML()
:打印 XML
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class XMLUtils {
private static final DocumentBuilderFactory documentBuilderFactory;
private static final TransformerFactory transformerFactory;
private static final DocumentBuilder documentBuilder;
static {
documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(false);
documentBuilderFactory.setValidating(false);
transformerFactory = TransformerFactory.newInstance();
try {
documentBuilder = documentBuilderFactory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new RuntimeException("无法创建 DOM 解析器", e);
}
}
/**
* 自定义的 NodeList 实现类
*/
private static class NodeListImpl implements NodeList {
private final List<Node> nodes = new ArrayList<>();
/**
* 添加节点到 NodeList 中
* @param node 要添加的节点
*/
private void addItem(Node node) {
nodes.add(node);
}
@Override
public Node item(int index) {
return nodes.get(index);
}
@Override
public int getLength() {
return nodes.size();
}
}
/**
* 将 NodeList 转换为 List
* @param nodeList 要转换的 NodeList 对象
* @return 转换后的 List
*/
public static List<Node> nodeListToList(NodeList nodeList) {
List<Node> list = new ArrayList<>();
for (int i = 0; i < nodeList.getLength(); i++) {
list.add(nodeList.item(i));
}
return list;
}
/**
* 将 List 转换为 NodeList
* @param list 要转换的 List 对象
* @return 转换后的 NodeList
*/
public static NodeList listToNodeList(List<Node> list) {
NodeListImpl nodeList = new NodeListImpl();
for (Node node : list) {
nodeList.addItem(node);
}
return nodeList;
}
/**
* 将 Node 转换为 Element
* @param node 要转换的节点
* @return 转换后的元素节点
*/
public static Element nodeToElement(Node node) {
try {
if (node.getNodeType() != Node.ELEMENT_NODE) {
throw new IllegalArgumentException("该节点不是元素节点");
}
return (Element) node;
} catch (IllegalArgumentException e) {
e.printStackTrace();
return null;
}
}
/**
* 将 Node 转换为 Attr
* @param node 要转换的节点
* @return 转换后的属性节点
*/
public static Attr nodeToAttr(Node node) {
try {
if (node.getNodeType() != Node.ATTRIBUTE_NODE) {
throw new IllegalArgumentException("该节点不是属性节点");
}
return (Attr) node;
} catch (IllegalArgumentException e) {
e.printStackTrace();
return null;
}
}
/**
* 将 Node 转换为 Text
* @param node 要转换的节点
* @return 转换后的文本节点
*/
public static Text nodeToText(Node node) {
try {
if (node.getNodeType() != Node.TEXT_NODE) {
throw new IllegalArgumentException("该节点不是文本节点");
}
return (Text) node;
} catch (IllegalArgumentException e) {
e.printStackTrace();
return null;
}
}
/**
* 将 Element 转换为 Node
* @param element 要转换的元素节点
* @return 转换后的节点
*/
public static Node elementToNode(Element element) {
return element;
}
/**
* 将 Attr 转换为 Node
* @param attr 要转换的属性节点
* @return 转换后的节点
*/
public static Node attrToNode(Attr attr) {
return attr;
}
/**
* 将 Text 转换为 Node
* @param text 要转换的文本节点
* @return 转换后的节点
*/
public static Node textToNode(Text text) {
return text;
}
/**
* 将 XML 字符串转换为 Document 对象
* @param xmlStr XML 字符串
* @return Document 对象
*/
public static Document strToDoc(String xmlStr) {
try {
// 创建一个 InputSource 对象来包装 XML 字符串
InputSource inputSource = new InputSource(new StringReader(xmlStr));
// 解析 XML 字符串并返回 Document 对象
Document document = documentBuilder.parse(inputSource);
// 将文档标准化
document.normalize();
return document;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将 Document 对象转换为 XML 字符串
* @param document 要转换的 Document 对象
* @return 转换后的 XML 字符串
*/
public static String docToStr(Document document) {
String xmlStr = "";
try {
// 创建一个新的转换器对象
Transformer transformer = transformerFactory.newTransformer();
// 设置转换器属性
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
// 创建一个字符输出流
StringWriter writer = new StringWriter();
// 将 Document 对象转换为 XML 字符串,并写入字符输出流
transformer.transform(new DOMSource(document), new StreamResult(writer));
// 将字符输出流转换为字符串并赋值给 xmlStr
xmlStr = writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return xmlStr;
}
/**
* 获取指定节点的所有子节点
* @param node 父节点
* @return 所有子节点列表
*/
public static List<Node> getChildNodes(Node node) {
List<Node> childNodes = new ArrayList<>();
// 获取所有子节点
NodeList nodeList = node.getChildNodes();
// 遍历所有子节点
for (int i = 0; i < nodeList.getLength(); i++) {
Node childNode = nodeList.item(i);
childNodes.add(childNode);
}
return childNodes;
}
/**
* 获取指定元素的所有子元素
* @param element 父元素
* @return 所有子元素列表
*/
public static List<Element> getChildElements(Element element) {
List<Element> childElements = new ArrayList<>();
// 获取所有子节点
NodeList nodeList = element.getChildNodes();
// 遍历所有子节点
for (int i = 0; i < nodeList.getLength(); i++) {
Node childNode = nodeList.item(i);
// 判断节点类型是否为元素节点
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
// 将元素节点添加到列表中
childElements.add((Element) childNode);
}
}
return childElements;
}
/**
* 获取元素所有属性
* @param element 元素节点
* @return 属性列表
*/
public static List<Attr> getElementAttrs(Element element) {
List<Attr> attributes = new ArrayList<>();
// 获取元素的属性集合
NamedNodeMap attributeMap = element.getAttributes();
// 遍历属性集合
for (int i = 0; i < attributeMap.getLength(); i++) {
Node attributeNode = attributeMap.item(i);
// 判断节点类型是否为属性节点
if (attributeNode.getNodeType() == Node.ATTRIBUTE_NODE) {
// 将属性节点添加到列表中
attributes.add((Attr) attributeNode);
}
}
return attributes;
}
/**
* 从指定文件名读取 XML 文件并返回 Document 对象
* @param filename XML 文件名
* @return Document 对象
*/
public static Document readXMLFile(String filename) {
// 创建一个文件对象
File xmlFile = new File(filename);
try {
// 创建一个FileInputStream对象
FileInputStream fis = new FileInputStream(xmlFile);
// 解析XML文件并返回Document对象
Document doc = documentBuilder.parse(fis);
return doc;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 打印 XML 文档
* @param doc XML文档对象
*/
public static void printXML(Document doc) {
Element root = doc.getDocumentElement();
printXML(System.out, root, 0);
}
/**
* 打印 XML 元素及其属性、子元素
* @param element XML元素
*/
public static void printXML(Element element) {
printXML(System.out, element, 0);
}
private static void printXML(PrintStream ps, Element element, int indent) {
printTrunk(ps, indent);
ps.printf("├─ 元素: %s\n", element.getNodeName());
NamedNodeMap attributes = element.getAttributes();
for (int i = 0; i < attributes.getLength(); i++) {
Attr attribute = (Attr) attributes.item(i);
printTrunk(ps, indent + 1);
ps.printf("├─ 属性: %s = %s\n", attribute.getName(), attribute.getValue());
}
NodeList children = element.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
printXML(ps, (Element) child, indent + 1);
} else if (child.getNodeType() == Node.TEXT_NODE) {
String text = child.getNodeValue().trim();
if (!text.isEmpty()) {
printTrunk(ps, indent + 1);
ps.printf("└─ 文本: %s\n", text);
}
}
}
}
/**
* 根据缩进层数打印树干,也就是前置"| "
* @param ps 打印流
* @param indent 缩进层数
*/
private static void printTrunk(PrintStream ps, int indent) {
for (int i = 0; i < indent; i++) {
ps.print("| ");
}
}
}
文章出处登录后可见!
已经登录?立即刷新