JavaXML处理工具类XMLUtils

本工具类基于 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("|   ");
        }
    }
}

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
乘风的头像乘风管理团队
上一篇 2023年12月28日
下一篇 2023年12月28日

相关推荐