Dom4j用Xpath获取节点——(六)

xml文档

<?xml version="1.0" encoding="utf-8"?>

<书架> 
  <> 
    <书名 name="ww">一本烂书!!</书名>  
    <作者>武陟县</作者>  
    <价格>200元</价格> 
  </>  
  <> 
    <书名 name="xxxxxxxxxxx">Java中级</书名>  
    <作者>打火机</作者>  
    <价格>2000元</价格> 
  </> 
</书架>

 

Java代码

package Dom4j_XMLParser;

import java.io.File;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;

public class Demo3 {
    /**
     * 测试path
     *@throws Exception
     */
    @Test
    public void xpathTest() throws Exception {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book.xml"));
        
        
//        获取所有节点
       List<Node> selectNodes = document.selectNodes( "//*" );
       for(Node node :selectNodes){
           System.out.println(node.asXML());
       }
        
//        取第一个书节点
        Element node = (Element) document.selectSingleNode( "//书名" );
        System.out.println(node.asXML());    //<书名 name="ww">一本烂书!!</书名>
        System.out.println(node.attributeValue("name"));   
        System.out.println(node.getText());
        
//        取第二个书的书名
        Node node1 = document.selectSingleNode( "/书架/书[last()]/书名" );
        System.out.println(node1.getText());
        
        
    }
}

 

 

结果:

<书架> 
  <> 
    <书名 name="ww">一本烂书!!</书名>  
    <作者>武陟县</作者>  
    <价格>200元</价格> 
  </>  
  <> 
    <书名 name="xxxxxxxxxxx">Java中级</书名>  
    <作者>打火机</作者>  
    <价格>2000元</价格> 
  </> 
</书架>
<> 
    <书名 name="ww">一本烂书!!</书名>  
    <作者>武陟县</作者>  
    <价格>200元</价格> 
  </>
<书名 name="ww">一本烂书!!</书名>
<作者>武陟县</作者>
<价格>200元</价格>
<> 
    <书名 name="xxxxxxxxxxx">Java中级</书名>  
    <作者>打火机</作者>  
    <价格>2000元</价格> 
  </>
<书名 name="xxxxxxxxxxx">Java中级</书名>
<作者>打火机</作者>
<价格>2000元</价格>
<书名 name="ww">一本烂书!!</书名>
ww
一本烂书!!
Java中级

 

 

 

 

什么是 XPath?

 

 

补充:dom4j用xpath获取节点之后修改属性后保存

例如:如下节点,需求是将court节点中cj属性是基层中没有q属性的节点找出来,赋予一个新的初始值,并将处理的节点单独写到另一个文件。

<?xml version="1.0" encoding="UTF-8"?>

<courts>
  <court id="112" q="宣武区" cj="基层"/>
  <court id="113" q="宣武区" cj="基层"/>
  <court id="114" cj="基层"/>
  <court id="115" cj="中层"/>
  <court id="116"/>
</courts>

代码如下:

package mvnpro;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class XMLClient2 {

    private static Map<String, Object> idNames = new HashMap<>();

    public static void main(String[] args) throws Exception {
        // 搜集区域信息
        handleXML();
    }

    private static void handleXML() throws Exception {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("F:/file/courts2.xml"));

        // 获取court节点(cj为基层并且不包含q属性的节点)
        String xpathPattern = "//court[@cj='基层' and not (@q)]";
        List<Element> selectNodes = document.selectNodes(xpathPattern);
        if (CollectionUtils.isEmpty(selectNodes)) {
            return;
        }

        List<String> matchedElements = new ArrayList<>();
        for (Element node : selectNodes) {
            node.setAttributeValue("q", "初始值");
            // 记录到成功的列表
            matchedElements.add(node.asXML());
        }

        // 修改完节点之后直接保存,保存后的xml节点顺序不会变,而且会保存修改后的节点属性
        write(document);
        // 保存处理成功和失败的记录到xml中便于手动排查
        write(matchedElements, "F:/file/courts2-successful.xml");
    }

    private static void write(List<String> nodes, String path) {
        if (CollectionUtils.isEmpty(nodes)) {
            return;
        }

        try {
            FileUtils.writeLines(new File(path), nodes);
            log.debug("writeLines success! path: {}", path);
        } catch (IOException e) {
            log.error("FileUtils.writeLines error", e);
        }
    }

    private static void write(Document document) throws Exception {
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("utf-8");
        XMLWriter writer = new XMLWriter(new FileOutputStream("F:/file/courts2-1.xml"), format);
        writer.write(document);
        writer.close();
        log.debug("write document success");
    }
}

结果:

counts2-1.xml如下:

<?xml version="1.0" encoding="utf-8"?>

<courts> 
  <court id="112" q="宣武区" cj="基层"/>  
  <court id="113" q="宣武区" cj="基层"/>  
  <court id="114" cj="基层" q="初始值"/>  
  <court id="115" cj="中层"/>  
  <court id="116"/> 
</courts>

courts2-successful.xml内容如下:

<court id="114" cj="基层" q="初始值"/>

 

Xml中文手册:

https://wenku.baidu.com/view/9fec55d86f1aff00bfd51e04.html

 

posted @ 2017-08-03 17:10  QiaoZhi  阅读(3142)  评论(0编辑  收藏  举报