Java中解析XML的方法

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;
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值