XML的4中常见解析方式

XML解析功能解析特别常见,比如:Spring,Hibernate,MyBatis等优秀的开源框架中都使用了xml作为其主要的配置文件,再框架启动时都需要去解析xml中配置的内容,下面将介绍常见的4中xml解析方式,并给出示例。

1、使用原生Dom解析XML

xml文件内容示例:

<?xml version="1.0" encoding="UTF-8"?>
<users>
  <user id="0">
    <name>Alexia</name>
    <age>23</age>
    <sex>Female</sex>
  </user>
  <user id="1">
    <name>Edward</name>
    <age>24</age>
    <sex>Male</sex>
  </user>
</users>

公共接口代码示例:

package com.wangbing.inter;

public interface XmlDocument {
  /**
   * 定义一个文档解析的接口,对于不同的方式进行不同的实现,此接口公用
   * @param fileName
   */
  public void parserXml(String fileName);
}

使用Dom解析xml示例代码:

public class DomDemo implements XmlDocument {
  public void parserXml(String fileName) {
    try {
      DocumentBuilderFactory dbf = 
              DocumentBuilderFactory.newInstance();
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document document = db.parse(fileName);
      NodeList users = document.getChildNodes();

      for (int i = 0; i < users.getLength(); i++) {
        Node user = users.item(i);
        NodeList userInfo = user.getChildNodes();

        for (int j = 0; j < userInfo.getLength(); j++) {
          Node node = userInfo.item(j);
          NodeList userMeta = node.getChildNodes();

          for (int k = 0; k < userMeta.getLength(); k++) {
            if(userMeta.item(k).getNodeName() != "#text")
               System.out.println(userMeta.item(k).getNodeName()
                   + ":" + userMeta.item(k).getTextContent());
            }
            System.out.println();
          }
       }
     } catch (FileNotFoundException e) {
       e.printStackTrace();
     } catch (ParserConfigurationException e) {
       e.printStackTrace();
     } catch (SAXException e) {
       e.printStackTrace();
     } catch (IOException e) {
       e.printStackTrace();
     }
  }
  public static void main(String[] args){
    new DomDemo().parserXml("D:"+ File.separator + "test.xml");
  }
}

优点:

(1)允许应用程序对数据和结构做出更改。
(2)访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据。

缺点:

通常需要加载整个XML文档来构造层次结构,消耗资源大。

2、使用Dom4j解析XML

示例:

public class Dom4jDemo implements XmlDocument {

  @SuppressWarnings("rawtypes")
  public void parserXml(String fileName) {
    File inputXml = new File(fileName);
    SAXReader saxReader = new SAXReader();
    try {
      Document document = saxReader.read(inputXml);
      Element users = document.getRootElement();
      for (Iterator i = users.elementIterator(); i.hasNext();) {
        Element user = (Element) i.next();
        for (Iterator j = user.elementIterator(); j.hasNext();) {
         Element node = (Element) j.next();
         System.out.println(node.getName() + ":" + node.getText());
        }
        System.out.println();
      }
    } catch (DocumentException e) {
      System.out.println(e.getMessage());
    }
  }
  public static void main(String[] args) {
    new Dom4jDemo().parserXml("src" + File.separator + "test.xml");
  }
}

优点:

(1)大量使用了Java集合类,方便Java开发人员,同时提供一些提高性能的替代方法。
(2)支持XPath。
(3)有很好的性能。

缺点:

大量使用了接口,API较为复杂。

3、使用SAX解析XML

示例:

public class SaxDemo implements XmlDocument {
  public void parserXml(String fileName) {
    SAXParserFactory saxfac = SAXParserFactory.newInstance();

    try {
      SAXParser saxparser = saxfac.newSAXParser();
      InputStream is = new FileInputStream(fileName);
      saxparser.parse(is, new MySAXHandler());
    } catch (ParserConfigurationException e) {
      e.printStackTrace();
    } catch (SAXException e) {
      e.printStackTrace();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

MySAXHandler类:

class MySAXHandler extends DefaultHandler {
  boolean hasAttribute = false;
  Attributes attributes = null;
  public void startElement(String uri, String localName, String qName,
    Attributes attributes) throws SAXException {
    if (qName.equals("users")) {
      return;
    }
    if (qName.equals("user")) {
      return;
    }
    if (attributes.getLength() > 0) {
      this.attributes = attributes;
      this.hasAttribute = true;
    }
  }

  public void endElement(String uri, String localName, String qName)
    throws SAXException {
    if (hasAttribute && (attributes != null)) {
      for (int i = 0; i < attributes.getLength(); i++) {
        System.out.print(attributes.getQName(0) + ":"
          + attributes.getValue(0));
      }
    }
  }

  public void characters(char[] ch, int start, int length)
    throws SAXException {
    System.out.print(new String(ch, start, length));
  }
  // 测试方法
  public static void main(String[] args){
    new SaxDemo().parserXml("src"+ File.separator + "test.xml");
  }
}

优点:

(1)不需要等待所有数据都被处理,分析就能立即开始。
(2)只在读取数据时检查数据,不需要保存在内存中。
(3)可以在某个条件得到满足时停止解析,不必解析整个文档。
(4)效率和性能较高,能解析大于系统内存的文档。

缺点:

(1)需要应用程序自己负责TAG的处理逻辑(例如维护父/子关系等),使用麻烦。
(2)单向导航,很难同时访问同一文档的不同部分数据,不支持XPath。

4、Jdom解析XML

示例:

public class JDomDemo implements XmlDocument {

  @SuppressWarnings("rawtypes")
  public void parserXml(String fileName) {
    SAXBuilder builder = new SAXBuilder();

    try {
      Document document = builder.build(fileName);
      Element users = document.getRootElement();
      List userList = users.getChildren("user");

      for (int i = 0; i < userList.size(); i++) {
        Element user = (Element) userList.get(i);
        List userInfo = user.getChildren();

        for (int j = 0; j < userInfo.size(); j++) {
          System.out.println(((Element) userInfo.get(j)).getName()
             + ":" + ((Element) userInfo.get(j)).getValue());
        }
        System.out.println();
      }
    } catch (JDOMException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  public static void main(String[] args){
    new SaxDemo().parserXml("src"+ File.separator + "test.xml");
  }
}

优点:

(1)使用具体类而不是接口,简化了DOM的API。
(2)大量使用了Java集合类,方便了Java开发人员。

缺点:

(1)没有较好的灵活性。
(2)性能较差。

以上介绍了常见的4中XML解析方法以及其各自的优缺点,使用的时候可以根据实际情况进行选择。

注:文章属作者原创,如果转发,请标注出处:https://www.jinnianshizhunian.vip