前端---DOM解析与Xpath定位

解析xml文件

DOM解析–>基于面向对象的方式:好理解

工具:dom4j-1.6.1-jar
DOM解析就是通过读取xml文件获取节点对象,通过节点对象更改标签的文本或属性。
步骤
1.写好指定的xml文件
2.创建xml解析对象 SAXReader saxReader=new SAXReader();
3.利用解析器对象的read(url目录资源的地址/绝对地址)

  • 绝对路径Document document=saxReader.read(url);
  • 读取maven工程的classes下面的资源文件:获取当前类字节码文件对象Document document=saxReader.read(当前类.class.getClassLoader().getResource("XXX.xml"));

4.返回一个document对象–>解析的过程中通过xml中的解析器形成dom树

DOM解析:由SAXReaer解析器,内置了一个解析引擎,遇到第一个标签,则将第一个标签作为根节点rootElement,后面解析标签的标签都开始进行排列,作为它子元素进行排列
解析的内容:标签->解析为接口Element 属性->解析为接口Attribute 文本->解析为接口Text

dom4j中获得标签对象的方法:

1.创建解析器对象SAXReader reader =new SAXReader();
2.加载资源文件Document doc=reader.read("url");
3.基本API:获取根节点对象:getRootElement()
获取一个普通标签之前,必须获得其父标签:Element conList=doc.getRootElement();
获取标签名称:conList.getName();
获取第一个子标签对象:conList.element(“标签名”);
获取同名的所有子节点对象(返回的是集合):conList.elements("标签名称");
获取当前根节点下的所有子节点conList.elements();

dom4j中获得属性的方法:

获取属性的前提是获取所在标签对象
获得属性的两种方法:
1.标签对象.attributeValue("属性名称");返回值为String
2.标签对象.attribute(“属性名称”);返回值为Attribute类型

  • attribute对象.getValue()

dom4j中获得文本的方法:

两种方法:
1.标签对象.getText();
2.父标签对象.elementText(“子节点名称”);

XML中的空格换行是文本内容,会被解析出来

读取完xml文件后将每一个标签封装为对象进行遍历

步骤:1.创建LIst集合对象
2.使用dom4j解析xml文件得到Document对象
3.document对象获取所有同名的子节点列表放入节点集合
4.遍历集合,获取到每一个标签,封装到标签集合
5.遍历集合,输出到打印台

package www.github.sweeeeeet.web_xml;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.util.ArrayList;
import java.util.List;

/**
 * Author:sweet
 * Created:2019/4/17
 */

    public class Contact {
    private String id;
    private String name;
    private String gender;
    private String phone;
    private String address;
    private String email;

    public Contact() {
        this.id = id;
        this.name = name;
        this.gender = gender;
        this.phone = phone;
        this.address = address;
        this.email = email;
    }

    @Override
    public String toString() {
        return "Contact{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", phone='" + phone + '\'' +
                ", address='" + address + '\'' +
                ", email='" + email + '\'' +
                '}';
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }



public static List<Contact> getContactXML() throws DocumentException {
    /*
     * 获取文本:先获取标签对象,再获取文本{
     * 1.父标签对象.elementText()
     * 2.标签对象.getText();
     * */
    //读取xml文件-->List<Concat>
    Document doc= new SAXReader()
            .read(Contact.class.getClassLoader().getResource("concat.xml"));
    //创建List集合
    List<Contact> list=new ArrayList<Contact>();
    //获取当前所有同名的contact 标签
    List<Element> conList=doc.getRootElement().elements("contact");
    for(Element e:conList){
        Contact contact=new Contact();
        contact.setId(e.attributeValue("id"));
        contact.setName(e.elementText("name"));
        contact.setEmail(e.elementText("email"));
        contact.setPhone(e.elementText("phone"));
        contact.setGender(e.elementText("gender"));
        contact.setAddress(e.elementText("address"));
        list.add(contact);
    }
    //遍历List集合
    for(Contact contact:list){
        System.out.println(contact);
    }

return list;
}


    public static void main(String[] args) {
        try {
            getContactXML();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

dom4j对XML操作的API

解析XML文件获取document对象:Document doc= new SAXReader() .read(Contact.class.getClassLoader().getResource("concat.xml"));
输出到文件

 //添加到D盘
            //创建输出流对象
            OutputStream outputStream=new FileOutputStream(
                    new File("D:\\Test\\contact.xml"));
            /*
             * createPrettyPrint:优雅文件格式,有空格
             * createCompactFormat():紧凑格式,用于部署上线
             * */
            OutputFormat format=OutputFormat.createPrettyPrint();
            format.setEncoding("utf-8");
            //创建输出对象,传递流对象和输出格式
            XMLWriter writer=new XMLWriter(outputStream,format);
            writer.write(document);
            writer.close();
增删改XML文件

1.获取document对象
2.调用API进行修改

添加一个空文档,获得一个文档对象:Document document=DocumentHelper.createDocument();
添加根节点(添加的第一个节点就是根节点): Element root= document.addElement("根节点名称");
添加标签对象根节点对象.addElement("标签名");
添加文本内容标签对象.addText("文本内容");

修改标签属性

  • 1.通过直接修改的方法
    1)通过父标签获取子标签对象(若有则获取,没有则创建):Element ele=document对象.getRootElement().element("标签名");
    2)通过标签对象获取属性对象:Attributr attr=父标签对象.attribute("属性名");
    3)通过属性对象修改属性值:属性对象.setValue("属性值");

  • 2.通过添加属性的方法
    添加属性值(如有则覆盖其属性的属性值):标签对象.addAttribute("属性",“属性值”);

修改文本内容
1)获取标签对象Element ele=document对象.getRootElement().element("标签名");
2)修改文本内容:标签对象.setText("文本内容");

通过根节点删除指定标签

  • 1.detach()方法
    1)通过根节点获取标签对象:Element ele=文档对象.getRootElement().element("标签名");
    2)通过标签对象自删:标签对象.detach();
  • remove()方法
    1)获取父标签对象:Element ele=当前标签对象.getParent();
    2)删除子节点对象:父标签对象.remove(指定标签对象);

dom4j的弊端:一次性加载文本(可能会导致OOM(大量记载图片/电商网站))

xpath解析

使用dom4j传统方式删除标签,太过复杂耗时;使用xpath解析XML文件,可以快速定位标签位置。
需要在maven中导入jaxen依赖包

<dependencies>
    <dependency>
        <!--提供Xpath表达式,快速定位标签-->
        <groupId>jaxen</groupId>
        <artifactId>jaxen</artifactId>
        <version>1.1.6</version>
        <type>bundle</type>
    </dependency>
</dependencies>

Xpath常用语法:

/:表示绝对路径;在xml中,/在标签名的前面,表示选中当前标签/concat-list:定位到根节点
/在标签名的中间,表示选中当前标签的子节点。/concat-list/concat选中字节点标签concat
//:不分层级关系,定位所有层级标签//concat 不分层级关系选中所有的concat
*:表示通配符/concat-list/*选中caoncat-list标签下的所有子节点(不包括孙节点)
[]:进一步定位元素
@:定位属性@属性名称
=:确定属性值或文本值[@id='001']确定id=001的标签
and 逻辑与
text()=’’:定位xxx的文本内容

API接口:
Node node=selectSingleNode(表达式)
Lise node=selectSingleNodes(表达式);

猜你喜欢

转载自blog.csdn.net/weixin_42962924/article/details/89362190