JavaEE XML XPath

JavaEE XML XPath

@author ixenos

 

 

XPath技术

1 引入

问题:当使用dom4j查询比较深的层次结构的节点(标签,属性,文本),比较麻烦!!!需要遍历DOM树的众多节点来进行查找!

比如rootEle.element(“dsfs”).element(“sdfsf”)element(“sdfsf”). element(“aim”)

 

2 xPath作用

主要是用于快速获取所需的节点对象。

(XSLT中的match属性的值就使用XPath!!!)

 

3 在dom4j中如何使用xPath技术

1)导入xPath支持jar包 。  jaxen-1.1-beta-6.jar

2)使用xpath方法

List<Node>  selectNodes("xpath表达式");   查询多个节点对象

Node       selectSingleNode("xpath表达式");  查询一个节点对象

 

4 xPath语法

/      绝对路径      表示从xml的根位置开始或子元素(一个层次结构)

//     相对路径       表示不分任何层次结构的选择元素。

*      通配符         表示匹配所有元素

[]      条件           表示选择什么条件下的元素

@     属性            表示选择属性节点

and     关系          表示条件的与关系(等价于&&)

text()    文本           表示选择文本内容

 

示例:

XPath可以描述XML文档中的一个节点集

/grib/row 

描述了grib的子元素(每一个grib)中所有的row元素

 

/grib/row[1] 

用[]选择特定元素,这表示第一行(索引从1开始)

 

/grib/row[1]/cell[1]/@anchor

用@得到属性值,这描述了第一行第一个单元格的anchor属性

 

/grib/row/cell/@anchor

描述了作为根元素的grib的子元素的那些row元素中所有cell的anchor属性

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
 * 1.   /      绝对路径      表示从xml的根位置开始或子元素(一个层次结构)
 */
xpath = "/contactList";
xpath = "/contactList/contact";
 
/**
 * 2. //     相对路径       表示不分任何层次结构的选择元素。
 */
xpath = "//contact/name";
xpath = "//name";
 
/**
 * 3. *      通配符         表示匹配所有元素
 */
xpath = "/contactList/*"; //根标签contactList下的所有子标签
xpath = "/contactList//*";//根标签contactList下的所有标签(不分层次结构)
 
/**
 * 4. []      条件           表示选择什么条件下的元素
 */
//带有id属性的contact标签
xpath = "//contact[@id]";
//第二个的contact标签
xpath = "//contact[2]";
//选择最后一个contact标签
xpath = "//contact[last()]";
 
/**
 * 5. @     属性            表示选择属性节点
 */
xpath = "//@id"; //选择id属性节点对象,返回的是Attribute对象
xpath = "//contact[not(@id)]";//选择不包含id属性的contact标签节点
xpath = "//contact[@id='002']";//选择id属性值为002的contact标签
xpath = "//contact[@id='001' and @name='eric']";//选择id属性值为001,且name属性为eric的contact标签
 
/**
 *6.  text()   表示选择文本内容
 */
//选择name标签下的文本内容,返回Text对象
xpath = "//name/text()";
xpath = "//contact/name[text()='张三']";//选择姓名为张三的name标签

  更多XPath表达式请看XPath Tutorial

 

Demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.io.File;
import java.io.FileOutputStream;
 
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
 
/**
 * 第一个xpath程序
 * @author ixenos
 *
 */
public class Demo1 {
 
 
    public static void main(String[] args) throws Exception{
        /**
         * 需求: 删除id值为2的学生标签
         */
        Document doc = new SAXReader().read(new File("e:/student.xml"));
 
        //1.查询id为2的学生标签
        //使用xpath技术
        Element stuElem = (Element)doc.selectSingleNode("//Student[@id='2']");
 
        //2.删除标签
        stuElem.detach();
 
        //3.写出xml文件
        FileOutputStream out = new FileOutputStream("e:/student.xml");
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("utf-8");
        XMLWriter writer = new XMLWriter(out,format);
        writer.write(doc);
        writer.close();
    }
 
}

  

 

 

简要示例


 1) 用XPath定位标签,进行修改操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package com.ixenos.xpath;
 
import java.util.List;
 
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
 
import com.ixenos.dom4j.CreateXML;
 
/**
 * 在TestXPath的基础上改进了:
 * 将精准定位全交给XPath去做,因此删除了modEle多余的属性定位判断
 *
 * @author ixenos
 *
 */
public class TestXPath2 {
 
    /**
     * 读取XML文件生成Docment
     *
     * @throws Exception
     */
    public static Document getDoc(String path) throws Exception {
        Document doc = new SAXReader().read(path);
        return doc;
    }
 
    /**
     * XPath定位标签
     */
    @SuppressWarnings("unchecked")
    public static List<Element> getEle(Document doc, String xpath) {
        return (List<Element>)doc.selectNodes(xpath);
    }
 
    /**
     * 对指定标签的子节点进行修改
     *
     * @param func
     *            修改功能选择
     * @param eleList
     *            被修改的标签list
     * @param aimChild
     *            想要修改的子标签
     * @param aimChildText
     *            想要修改的新的子标签文本值
     */
    public static void modEle(String func, List<Element> eleList, String aimChild, String aimChildText) {
        // 取出
        for (Element ele : eleList) {
            // 修改功能选择
            if ("delete".equals(func)) {
                ele.detach();
            } else if ("modify".equals(func)) {
                // 修改指定子节点的文本值
                // element(name)指定第一个标签名为name的标签
                // setText修改Text,addText追加Text
                ele.element(aimChild).setText(aimChildText);
            }
        }
 
    }
 
    /**
     * 将DOM树输出为XML文件
     *
     * @throws Exception
     */
    public static void writeXML(Document doc, Boolean pretty, String encoding) throws Exception {
        CreateXML.writeXML(doc, pretty, encoding);
    }
 
    /**
     * 测试
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        Document doc = getDoc("demo.xml");
         
        //得到所有id属性值为2的Student标签
        List<Element> eleList = getEle(doc, "//Student[@id='2']");
 
        modEle("modify", eleList, "name", "尔雅");
        // modEle("delete", eleList, null, null);
        writeXML(doc, true, "utf-8");
 
    }
}

  

修改结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?>
 
<Students>
  <Student id="1">
    <name>张三</name
    <gender>男</gender
    <grade>物联网一般</grade
    <address>广州白云</address>
  </Student
  <Student id="2">
    <name>尔雅</name
    <gender>女</gender
    <grade>物联网二班</grade
    <address>广州海珠</address>
  </Student>
</Students>

  

 2) 用XPath读取一个规范的html文件(比如xhtml)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import java.io.File;
import java.util.Iterator;
import java.util.List;
 
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
 
/**
 * 使用xpath技术读取一个规范的html文档
 * @author ixenos
 *
 */
public class Demo4 {
 
    public static void main(String[] args) throws Exception{
        Document doc = new SAXReader().read(new File("./src/personList.html"));
        //System.out.println(doc);
 
        //读取title标签
        Element titleElem = (Element)doc.selectSingleNode("//title");
        String title = titleElem.getText();
        System.out.println(title);
 
        /**
         * 练习:读取联系人的所有信息
         * 按照以下格式输出:
         *       编号:001 姓名:张三 性别:男 年龄:18 地址:xxxx 电话: xxxx
         *       编号:002 姓名:李四 性别:女 年龄:20 地址:xxxx 电话: xxxx
         *       ......
         */
        //1.读取出所有tbody中的tr标签
        List<Element> list = (List<Element>)doc.selectNodes("//tbody/tr");
        //2.遍历
        for (Element elem : list) {
            //编号
            //String id = ((Element)elem.elements().get(0)).getText();
            String id = elem.selectSingleNode("td[1]").getText();
            //姓名
            String name = ((Element)elem.elements().get(1)).getText();
            //性别
            String gender = ((Element)elem.elements().get(2)).getText();
            //年龄
            String age = ((Element)elem.elements().get(3)).getText();
            //地址
            String address = ((Element)elem.elements().get(4)).getText();
            //电话
            String phone = ((Element)elem.elements().get(5)).getText();
 
            System.out.println("编号:"+id+"\t姓名:"+name+"\t性别:"+
                                gender+"\t年龄:"+
                                age+"\t地址:"+address+
                                "\t电话:"+phone);
        }
    }
}

  

posted @   ixenos  阅读(288)  评论(0编辑  收藏  举报
编辑推荐:
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
阅读排行:
· 从零开始开发一个 MCP Server!
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档
点击右上角即可分享
微信分享提示