JAVA WEB从入门到精通day07 Schema,dom4j,xpath的学习

本节思维导图

这里写图片描述

Schema学习

Schema简介

    XML Schema 是基于 XML 的 DTD 替代者。
    XML Schema 描述 XML 文档的结构
    XML Schema 语言也可作为 XSD(XML Schema Definition)来引用。

Schema作用

    -XML Schema 的作用是定义 XML 文档的合法构建模块,为XML文件添加约束,类似 DTD。
    -定义可出现在文档中的元素
    -定义可出现在文档中的属性
    -定义哪个元素是子元素
    -定义子元素的次序
    -定义子元素的数目
    -定义元素是否为空,或者是否可包含文本
    -定义元素和属性的数据类型
    -定义元素和属性的默认值以及固定值

Schema优点

    Schema是DTD的代替者,比DTD更加强大。
    (1)支持数据类型
    -可更容易地描述允许的文档内容
    -可更容易地验证数据的正确性、
    -可更容易地与来自数据库的数据一并工作
    -可更容易地定义数据约束

    (2)Schema文件本身也是XML文件,使用XML语法
    -可使用 XML 编辑器来编辑 Schema 文件
    -可使用 XML 解析器来解析 Schema 文件

    (3)Schema可保护数据通信

    (4)Schema可扩展
    -在一个文档中可以引用多个Schema

    (5)Schema可以捕获错误

Schema文档

    Schema文档后缀名为.xsd
    例如:
    <?xml version="1.0" encoding="UTF-8"?>  //xml文档声明
    <schema xmlns="http://www.w3.org/2001/XMLSchema" //固定。显示schema中用到的预定义的元素来自于w3c组织
    targetNamespace="XXXXX"  //可以随便写,一般写url地址,不容易重复。显示此schema定义的元素来自于这个命名空间。
     elementFormDefault="qualified">  //固定。显示schema中用到的预定义的元素来自于w3c组织

    </schema>

    在XML中引用Schema文件
    <根节点 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="schema文档中的targetNamespace的值"
    xsi:schemaLocation="targetNamespace的值 xsd文档的路径">
    </根节点>

XSD元素

    定义简易元素:<element name="xxx" type="yyy"></element>
    name代表元素的名称
    type代表元素的类型
    default代表元素的默认值
    fixed代表元素的固定值,不可更改

    定义复杂元素:包含子节点或其他元素的元素
    <element name="复杂元素名称">
        <complexType>
            <sequence>
            子节点1
            子节点2
            .......
            </sequence>
        </complexType>
    </element>

    例子
        <?xml version="1.0" encoding="UTF-8"?>
        <schema xmlns="http://www.w3.org/2001/XMLSchema" 
        targetNamespace="http://www.example.org/1" 
        xmlns:tns="http://www.example.org/1" 
        elementFormDefault="qualified">

        <element name="person">
            <complexType>
            <sequence>
                <element name="name" type="string"></element>
                <element name="age" type="int"></element>
            </sequence>
            </complexType>

        </schema>

Schema指示器

    <sequence></sequence>:规定元素必须按照指定的顺序出现
    <all></all>:规定元素可以按照任意顺序出现,且每个元素必须只出现一次
    <choice></choice>:规定只能出现其中的一个子元素

    元素属性里可以添加Occurrence指示器
    maxOccurs:规定元素可出现的最大次数
    minOccurs:规定元素出现的最小次数
    例子:
    <element name="xxx" type="yyy" maxOccurs="10" minOccurs"0"></element>
    如需使某个元素的出现次数不受限制,请使用 maxOccurs="unbounded" 这个声明

    <any></any>表示可以出现任何元素

SAX解析方式

SAX解析简介:

    -SAX解析是从头到尾逐个读取内容,修改不便,适用于只读的大文档。
    -SAX采用事件驱动的方式解析文档,就如同电影院看电影一样,从头到尾看一遍,不能回退。
    -SAX解析过程中,读取到文档开头结尾,元素开头结尾都会触发一些回调方法。
    这四个方法是:startDocument() 、 endDocument()、 startElement()、 endElement
    -此外,光读取到节点处是不够的,我们还需要characters()方法来仔细处理元素内包含的内容
    将这些回调方法集合起来,便形成了一个类,这个类也就是我们需要的触发器

    重要的方法有三个
    -读取到元素开始时自动调用startElement方法:
    void startElement(String uri, String localName, String qName, Attributes attributes)
    qName为元素名

    -读取文本内容时自动调用characters方法
    void characters(char[] ch, int start, int length)
    ch为字符数组,start为开始位置,length为长度,直接new String(ch,start,length)就可获得内容

    -读取到元素末尾时自动调用endElement方法
    void endElement(String uri, String localName, String qName)
    qName为元素名

SAX例子:查询所有元素

xml文件

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

<class> 
  <person id="001"> 
    <name>zhangsan</name>  
    <age>500</age>  
  </person>  
  <person> 
    <name>lisi</name>  
    <age>20</age> 
  </person> 
</class>
    //查询所有元素

        public class SaxTest {
        public static void main(String[] args) throws Exception {
                SAXParserFactory saxParserFactory=SAXParserFactory.newInstance(); //先创建解析器工厂
                SAXParser saxParser=saxParserFactory.newSAXParser();//通过解析器工厂获得解析器实例
                saxParser.parse("WebContent/class.xml", new myHandler());//然后传入被解析的xml文档和触发器,触发器需要自己继承DefaultHandler类
            }           
            }

//继承默认触发器,覆写里面的三个方法,这三个方法都是自动被调用的
        class myHandler extends DefaultHandler
        {
            //覆写三个方法
            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                // TODO Auto-generated method stub
                System.out.print("<"+qName+">");
            }

            @Override
            public void characters(char[] ch, int start, int length) throws SAXException {
                // TODO Auto-generated method stub
                System.out.print(new String(ch,start,length));
            }

            @Override
            public void endElement(String uri, String localName, String qName) throws SAXException {
                // TODO Auto-generated method stub
                System.out.println("</"+qName+">");
            }

        }

SAX例子:获取所有name标签里的值

    //自定义触发器里面的三个方法,里面的方法是文档被解析时自动被调用的
    class myHandler extends DefaultHandler
    {
        //设置一个标记
        boolean flag=false;
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            // TODO Auto-generated method stub
            //当标签为name时,标志设为true
            if(qName.equals("name"))
            {
                flag=true;
            }
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            // TODO Auto-generated method stub
            //如果标记为true,代表这是name标签,获取里面的值
            if(flag)
            {
            System.out.println(new String(ch,start,length));
            }
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            // TODO Auto-generated method stub
            //如果读取到name的末尾,就将标记设置为false
            if(qName.equals("name"))
            {
                flag=false;
            }
        }

    }

DOM4J

dom4j简介

    dom4j是一个Java的XML API,是jdom的升级品,用来读写XML文件的。
    dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点。

    获取解析器和document文档
    SAXReader reader=new SAXReader();
    Document document=reader.read(URL);

    Document下的方法
    getRootElement():获取根节点

    Element下的方法
    elements():获取标签下的所有子节点,返回值是list集合
    elements(QName qName):获取标签下的qName节点,返回值是list集合
    element(QName qName):获取标签下的第一个qName节点,返回值是Element

例子:dom4j实现查询操作

xml文档

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

            <class> 
              <person id="001"> 
                <name>zhangsan</name>  
                <age>500</age>  
              </person>  
              <person> 
                <name>lisi</name>  
                <age>20</age> 
              </person> 
            </class>
            //查询所有name标签里的值
            public static void selectName() throws Exception
            {
                //创建解析器
                SAXReader saxReader=new SAXReader();
                //获取document
                Document document=saxReader.read("WebContent/class.xml");
                //获取根节点
                Element root=document.getRootElement();
                //获取根节点下的所有person
                List <Element> list=root.elements("person");
                //遍历每一个person,获取name值
                for(Element element:list)
                {
                    Element name1=element.element("name");
                    String s=name1.getText();
                    System.out.println(s);
                }
            }


            //查询第一个name的值
            public static void selectFirst() throws Exception
            {
                //创建解析器
                SAXReader saxReader=new SAXReader();
                //获取document
                Document document=saxReader.read("WebContent/class.xml");
                //获取根节点
                Element root=document.getRootElement();
                //获取第一个person
                Element person=root.element("person");
                获取第一个name
                Element name=person.element("name");
                System.out.println(name.getText());
            }

例子:dom4j实现末尾添加节点的操作

//在第一个person里添加一个性别(sex)

        public static void addSex() throws Exception
        {
            //获取解析器
            SAXReader saxReader=new SAXReader();
            //获取document
            Document document=saxReader.read("WebContent/class.xml");
            //获取根节点
            Element root=document.getRootElement();
            //获取第一个person
            Element person=root.element("person");
            //添加节点到末尾
            Element sex=person.addElement("sex");
            //添加文本
            sex.addText("男");
            //回写操作
            OutputFormat format=OutputFormat.createPrettyPrint();//指定回写的格式,带缩进,一般用这种
            //OutputFormat format=OutputFormat.createCompactFormat();//这种格式全在一行,没缩进
            XMLWriter writer=new XMLWriter(new FileOutputStream("WebContent/class.xml"), format);//第一个参数为要写入的文件,第二个为格式
            writer.write(document);//把内存中的文档树写入到文件中
            writer.close();//关闭流
        }

例子:dom4j实现在特定位置添加节点

在第一个person里的name下面添加school标签

            public static void addIndex() throws Exception
            {
                //获取解析器
                SAXReader saxReader=new SAXReader();
                //获取document
                Document document=saxReader.read("WebContent/class.xml");
                //获取根节点
                Element root=document.getRootElement();
                //获取第一个person
                Element person=root.element("person");
                //获取person下的所有标签
                List <Element>list=person.elements();
                //创建标签
                Element school=DocumentHelper.createElement("school");
                //添加文本
                school.setText("黄淮学院");
                //然后通过list集合的add方法将节点添加到指定地方
                list.add(1, school);
                //回写
                OutputFormat format=OutputFormat.createPrettyPrint();
                XMLWriter xmlWriter=new XMLWriter(new FileOutputStream("WebContent/class.xml"),format);
                xmlWriter.write(document);
                xmlWriter.close();
            }

例子:使用dom4j修改节点

public static void update() throws Exception
        {
            //获取解析器
            SAXReader saxReader=new SAXReader();
            //获取document
            Document document=saxReader.read("WebContent/class.xml");
            //获取根节点
            Element root=document.getRootElement();
            //获取第一个person
            Element person=root.element("person");
            //获取person下的age
            Element age=person.element("age");
            //修改age
            age.setText("500");
            //回写操作
            OutputFormat format=OutputFormat.createPrettyPrint();
            XMLWriter xmlWriter=new XMLWriter(new FileOutputStream("WebContent/class.xml"),format);
            xmlWriter.write(document);
            xmlWriter.close();
        }

例子:通过dom4j删除节点

public static void del() throws Exception
        {
            //获取解析器
            SAXReader saxReader=new SAXReader();
            //获取document
            Document document=saxReader.read("WebContent/class.xml");
            //获取根节点
            Element root=document.getRootElement();
            //获取第一个person
            Element person=root.element("person");
            //获取person下的school节点
            Element school=person.element("school");
            //通过父节点进行删除
            person.remove(school);
            //回写操作
            OutputFormat format=OutputFormat.createPrettyPrint();
            XMLWriter xmlWriter=new XMLWriter(new FileOutputStream("WebContent/class.xml"),format);
            xmlWriter.write(document);
            xmlWriter.close();
        }

例子:通过dom4j获取属性的操作

public static void getAttr() throws Exception
        {
            SAXReader saxReader=new SAXReader();
            //获取document
            Document document=saxReader.read("WebContent/class.xml");
            //获取根节点
            Element root=document.getRootElement();
            Element person=root.element("person");
            //通过attributeValue()方法获取属性值
            String s=person.attributeValue("id");
            System.out.println(s);
        }

XPath学习

xpath简介

    -XPath即为XML路径语言,XPath 是一门在 XML 文档中查找信息的语言。
    -XPath 用于在 XML 文档中通过元素和属性进行导航。
    -XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。

XPath语法

        第一种形式:/AAA/BBB/CCC: 为树形结构,表示AAA下面的BBB下面的CCC节点

        第二种形式://BBB:不管在什么位置,选取所有BBB元素

        第三种形式:/*:选取这一层的所有元素

        第四种形式:
                /BBB[1]:表示这一层的第一个BBB元素
                /BBB[last()]:表示这一层的最后一个BBB元素

        第五种形式:
                //@id:表示选取所有的id属性
                //BBB[@id]:表示选择有id属性的BBB元素
                //BBB[@*]:表示选择有任意属性的BBB元素
                //BBB[not(@*)]:选择没有属性的BBB元素

        第六种形式:
                //BBB[@id='b1']:表示选取含有属性id并且id值为b1的BBB元素

        第七种形式://*[count(BBB=2)]:选择含有两个BBB元素的节点

使用dom4j支持xpath

        用dom4j查询虽然已经方便很多,但是每次查询都要一层一层的查,使用xpath可以
        快速的定位到需要的节点。

        要首先导入支持xpath的jar包。

        在dom4j里有提供两个方法、
        selectNodes("xpath表达式"):返回多个节点
        selectSingleNode("xpath表达式"):返回单个节点

例子:使用xpath查询所有name节点的值

public static void selectAll() throws Exception
        {
            //获取解析器
            SAXReader saxReader=new SAXReader();
            //获取document文档
            Document document=saxReader.read("WebContent/class.xml");
            //使用selectNodes方法查询xpath语法获得集合
            List <Node> list= document.selectNodes("//name");
            for(Node node:list)
            {
                String s=node.getText();
                System.out.println(s);
            }
        }

例子:使用xpath查询第一个person下面的name值

public static void selectFirst() throws Exception
            {
                SAXReader saxReader=new SAXReader();
                Document document=saxReader.read("WebContent/class.xml");
                //第一个person有id=‘001’,可以通过这个直接定位
                Node name=document.selectSingleNode("//person[@id='001']/name");
                String s=name.getText();
                System.out.println(s);;
            }

综合应用:学生管理系统XML文件的基本操作

student.xml

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

<school> 
  <class> 
    <student> 
      <id>001</id>  
      <name>张三</name>  
      <age>19</age> 
    </student>  
    <student> 
      <id>002</id>  
      <name>李四</name>  
      <age>30</age> 
    </student> 
  </class> 
</school>

例子:往student.xml文件中添加一个学生

public static void addStu() throws Exception
            {
                //创建解析器
                SAXReader saxReader=new SAXReader();
                //获取指定文档
                Document document=saxReader.read("WebContent/student.xml");
                //获取根节点
                Element root= document.getRootElement();
                //获取根节点下的class节点
                Element class1=root.element("class");
                //添加学生节点
                Element student=class1.addElement("student");
                //在学生节点下面依次添加id,name,age等节点
                Element id=student.addElement("id");
                Element name=student.addElement("name");
                Element age=student.addElement("age");
                //设置值
                id.setText("003");
                name.setText("王五");
                age.setText("30");
                //回写操作
                OutputFormat format=OutputFormat.createPrettyPrint();
                XMLWriter xmlWriter=new XMLWriter(new FileOutputStream("WebContent/student.xml"),format);
                xmlWriter.write(document);
                xmlWriter.close();  
            }

例子:删除学生

public static void delStu(String id) throws Exception
            {
                //创建解析器
                SAXReader saxReader=new SAXReader();
                //获取指定文档
                Document document=saxReader.read("WebContent/student.xml");
                //利用xpath获取所有id标签
                List<Node> list=document.selectNodes("//id");
                //通过循环判断哪个与传入的id相等
                for(Node node:list)
                {
                    //如果相等,就获得id的父节点的父节点,然后删除父节点
                    if((node.getText()).equals(id))
                    {
                        Element parent=node.getParent();
                        Element school=parent.getParent();
                        school.remove(parent);
                    }
                }
                //回写操作
                OutputFormat format=OutputFormat.createPrettyPrint();
                XMLWriter xmlWriter=new XMLWriter(new FileOutputStream("WebContent/student.xml"),format);
                xmlWriter.write(document);
                xmlWriter.close();  
            }

例子:查询学生

public static void selectStu(String id) throws Exception
        {
            //创建解析器
            SAXReader saxReader=new SAXReader();
            //获取指定文档
            Document document=saxReader.read("WebContent/student.xml");
            //获取所有id的集合
            List<Node> list=document.selectNodes("//id");
            //通过循环判断哪个与传入的id相等
            for(Node node:list)
            {
                //如果相等,就获得id的父节点,通过父节点来获取到所有学生的信息,进行打印
                if((node.getText()).equals(id))
                {
                    Element parent=node.getParent();
                    Element name=parent.element("name");
                    Element age=parent.element("age");
                    System.out.println("id:"+node.getText()+"name:"+name.getText()+"age:"+age.getText());
                }
            }
        }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值