Java中解析XML的方法

来源:互联网 发布:张国荣 唱功 知乎 编辑:程序博客网 时间:2024/06/06 02:49

XML 简单介绍

在介绍Java中解析 XML 的方法之前前先来介绍下 XML,在我之前学习 HTML 的时候,就听当时的老师介绍过 XML ,它和 HTML 一样是一种标记语言,不同的是它的语法更加灵活,HTML 中的标签是预定义的,而 XML 中的标签则由创建者自己定义,并且每个 XML 标签都是成对出现的 ,通常需要在文件的首行写上 XML 的一个文档头作为开始 其中可以包括版本,编码方式… XML 文档 和HTMl各种节点,节点也可以有属性,但其每一个属性都必须有属性值。
下面是一个 XML 文档内容,并将作为解析XML文档用例。

<!-- XML 中的注释 --><!-- 文档头 --><?xml version="1.0" encoding="UTF-8"?><!-- 根节点 --><struts>    <!-- 子节点、文本及属性 -->    <action name="login" class="com.tennyson.xml.LoginAction">        <result name="success">/jsp/homepage.jsp</result>        <result name="fail">/jsp/showLogin.jsp</result>    </action>    <action name="logout" class="com.tennyson.xml.LogoutAction">        <result name = "success">/jsp/welcome.jsp</result>        <result name = "error">/jsp/error.jsp</result>    </action></struts>

Java 中解析 XML 的方法

要在 Java 中使用 XML ,首先要解析它,Java 中有四种解析 XML 文档的方法,Java自身提供了两种解析XML 文档的方法:DOM 解析器和 SAX 解析器,也就是说在使用这两种方法时不用再引入jar包二直接使用。另外两种是 JDOM 和 DOM4J, 下面将会分别介绍。

DOM XML

DOM 解析器读入的 XML 文档解析后保留其树形结构,可以获取文档树中的上下文结构、信息,使用也比较简单。

DOM解析器把整个XML文档装载到内存,并解析成一个Document对象。
- 优点:元素与元素之间保留结构关系,故可以进行增删改查操作。
- 缺点:XML文档过大,可能出现内存溢出显现。

要读入一个 XML 文档需要 DocumentBuilder 对象,可以从 DocumentBuilderFactory 中获得该对象,之后即可使用 DocumentBuilder 对象读入文档。

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 获取 DocumentBuilder 对象DocumentBuilder builder = factory.newDocumentBuilder();// 读入 XML 文件,获得一个 Document 对象Document document = builder.parse("struts.xml");

Document 对象保留了文档树的结构,之后的操作与解析器无关。
可以通过 getDocumentElement() 获得文档的根节点,之后通过 getChildNodes() 获取根节点下的子节点,该方法将会返回一个 NodeList 集合

...// 获取文档根节点Element struts = document.getDocumentElement();// 枚举所有子节点NodeList strutsNodeList = struts.getChildNodes();for (int i = 0; i < strutsNodeList.getLength(); i++) {    Node childNode = strutsNodeList.item(i);    // 只获取子元素,而忽略空白字符    if (childNode instanceof Element) {        Element action = (Element) childNode;    }}

如果知道了获取的子节点中只有一个文本节点,则可以使用getFirstChild()获取到,并通过getData()获取到节点字符串,对getData()得到的返回值调用trim()方法可以将实际数据前后的空白字符删除掉。

同样可以使用getLastChild()方法得到最后一个子元素,使用getNextSibling()得到下一个兄弟节点

可以调用getAttributes()方法获取节点的所有属性,使用getNodeName()获取属性名getNodeValue()获取属性值,如果知道属性名可以使用getAttribute(“attributeName”)获取该属性值。

...// 根据属性名获取属性String attributeValue = action.getAttribute("name");

SAX

尽管使用 DOM 解析XML 文档操作简单,并且易于对 DOM 树增加或删除节点,但使用 DOM 解析器需要处理整个文档,当文档过大,或者你只需要处理文档中某个节点而不关注文档上下文时,使用 DOM 就显得效率低下,且占用内存资源,这是可以使用 SAX 解析器,SAX 解析器解析 XML 文档采用了基于事件的模型,在解析时触发一系列事件。

SAX相较于速度更快,更有效。它逐行扫描文档,一边扫描一边解析。并以事件驱动的方式进行具体解析,每执行一行,都将触发对应的事件。
- 优点:处理速度快,可以处理大文件
- 缺点:只能读,逐行后将释放资源

DOM4J

已解析一下XML文件为例,展示DOM4J的使用

<?xml version = “1.0” encoding=”UTF-8”?><products>    <product id = “p001”>        <name>华为X80</name>        <color></color>        <price>2800</price>    </product>    <product id = “p002”>        <name>华为X88</name>        <color></color>        <price>2900</price>    </product></products>

dom4j解析代码:

public class Test {    public static void main(String[] args) throws Exception {        List<Product> products = anaylysisXML("product.xml");        for (Product product : products) {            System.out.println(product);        }    }    @SuppressWarnings("unchecked")    public static List<Product> anaylysisXML(String fileName) throws Exception {        List<Product> list = new ArrayList<Product>();        // 使用dom4j解析XML文件,首先要获取SAXReader对象        SAXReader reader = new SAXReader();        // 加载XML文件的DOM树        Document doc = reader.read(fileName);        // 获取DOM树的根节点        Element root = doc.getRootElement();        // 获取根节点下的所有子节点        List<Element> elements = root.elements();        // 遍历节点        for (Element element : elements) {            Product product = new Product();            // 根据属性名获取属性值            Attribute id = element.attribute("id");            product.setId(id.getValue());            // 根据子节点名获取当前节点下子节点的文本值            String name = element.elementText("name");            String color = element.elementText("color");            Double price = Double.parseDouble(element.elementText("price"));            product.setName(name);            product.setColor(color);            product.setPrice(price);            /*             * //  获取当前节点下的所有子节点             * List<Element> elemList = element.elements();             *              * // 遍历节点             * for (Element node : elemList) {             *               *  // 获取当前节点的节点名             *  String nodeName = node.getName();             *  // 获取当前节点的文本值(文本节点)             *  String value = node.getText();             *  if ("name".equals(nodeName)) {             *      product.setName(value);             *  }             *               *  if ("color".equals(nodeName)) {             *      product.setColor(value);             *  }             *               *  if ("price".equals(nodeName)) {             *      product.setPrice(Double.parseDouble(value));             *  }             *             *                * }             */            list.add(product);        }        return list;    }}