• Xml


    1.XML基础

      一:作用

        作为软件配置文件;作为小型的数据库

      二:语法

        标签:标签名不能以数字开头,中间不能有空格,区分大小写,有且只有一个根标签

        属性:可以有多个属性,属性值必须用引号(单双都可以但不可以单双混用)

           文档声明:<?xml version="1.0" encoding="utf-8">

              encoding="utf-8": 打开或解析xml文档时的编码

              注意:保存xml文档时的编码 和 解析xml文档时的编码要保持一致,才能避免中文乱码问题!

      三:XML 解析

        程序读取或者操作xml文档

        解析方式:DOM解析 vs SAX解析

        (一)DOM解析:   

           DOM解析原理:一次性把xml文档加载成Document树,通过Document对象得到节点对象,通过节点对象访问xml文档内容(标签,属性,文本,注释)。

           使用工具:Dom4j工具    

           使用语法:

              a.读取xml文档

               Document doc = new SAXReader().read("xml文件");

                 节点:nodeIterator:所有节点;

                 标签:element("名字")指定名称的第一个子标签

                  elementIterator("名称");  指定名称的所有子标签对象

                  elements();  所有子标签对象

               属性:

                  attributeValue("名称")指定名称的属性值

                  attribute("名称")指定名称的属性对象

                  getName() 属性名称

                  getValue() 属性值

                  atributeIterator()   所有属性对象(Iterator)

                  attributes() 所有属性对象(List)

               文本:

                  getText()  得到当前标签的文本

                  elementText("子标签名称") 得到子标签的文本

              b.写Xml文档

                XMLWriter writer = new XMLWriter(OutputStream, OutputForamt)

                  wirter.write(Document);

              c.修改Xml文档的API

                增加:DocumentHelper.createDocument() 增加文档

                   addElement("名称") 增加标签

                   addAttribute("名称",“值”) 增加属性

                修改:Attribute.setValue("值") 修改属性值

                   Element.addAtribute("同名的属性名","值") 修改同名的属性值

                   Element.setText("内容") 修改文本内容

                删除:Element.detach(); 删除标签

                   Attribute.detach();  删除属性

    例子:

    /**
     *  课堂练习: 
     * 1.使用dom4j的api来生成以下的xml文件
    <Students>
    <Student id="1">
        <name>张三</name>
        <gender>男</gender>
        <grade>计算机1班</grade>
        <address>广州天河</address>
    </Student>
    <Student id="2">
        <name>李四</name>
        <gender>女</gender>
        <grade>计算机2班</grade>
        <address>广州越秀</address>
    </Student>
    </Students>
    
    2.修改id为2的学生的姓名,改为“王丽”
    
    3.删除id为2的学生
     * @author APPle
     *
     */
    public class Demo2 {
    
        public static void main(String[] args) throws IOException, Exception {
            // TODO Auto-generated method stub
            //第一题
            /*Document doc=DocumentHelper.createDocument();
            Element root=doc.addElement("Students");
            Element e1=root.addElement("Student");
            Element e11=e1.addElement("name");
            Element e12=e1.addElement("gender");
            Element e13=e1.addElement("grade");
            Element e14=e1.addElement("address");
            e1.addAttribute("id", "1");
            e11.setText("张三");
            e12.setText("男");
            e13.setText("计算机1班");
            e14.setText("广州天河");
            
            Element e2=root.addElement("Student");
            Element e21=e2.addElement("name");
            Element e22=e2.addElement("gender");
            Element e23=e2.addElement("grade");
            Element e24=e2.addElement("address");
            e2.addAttribute("id", "2");
            e21.setText("李四");
            e22.setText("女");
            e23.setText("计算机2班");
            e24.setText("广州越秀");
            
            XMLWriter writer=new XMLWriter(new FileOutputStream(new File("e:/b.xml")));
            writer.write(doc);*/
            
            //第二题
            Document doc1=new SAXReader().read(new File("e/b.xml"));
            Element ele1=doc1.getRootElement();
            @SuppressWarnings("unchecked")
            Iterator<Element> it=ele1.elementIterator();
            while(it.hasNext()){
                Element e=it.next();
                if(e.attributeValue("id").equals("2")){
                    e.element("name").setText("王丽");
                }
            }
            XMLWriter writer1=new XMLWriter(new FileOutputStream(new File("e:/bb.xml")));
            // 设置编码
            OutputFormat format = OutputFormat.createPrettyPrint();
            format.setEncoding("utf-8");
            writer1.write(doc1);
            
        }
    
    }
    View Code

        (二)xPath技术

             a.出现的原因:当使用dom4j查询比较深层次结构的节点(标签属性文本)比较麻烦!就出现这个能快速定位到xml中的具体位置

             b.作用:快速获取所需节点对象

             c.使用:1.导入xPath支持的jar包:jaxen-1.1-beta-6.jar

                 2.使用方法:List<Node> selectNodes("xpath表达式");查询多个节点对象

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

             d.语法:

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

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

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

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

                @ 属性 表示选择属性节点

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

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

    例子:

    /**
         * 删除id=002的学生标签
         * @param doc 
         * @param id
         * @throws IOException 
         * @throws Exception 
         */
        public static void deleById() throws IOException, Exception{
            Document doc=new SAXReader().read(new File("./src/XML/contact.xml"));
            //1.查询id为2的学生标签
            //使用xpath技术
            Element ee=(Element)doc.selectSingleNode("//contact[@id='002']");
            //删除标签
            ee.detach();
            //写回去
            FileOutputStream fos=new FileOutputStream("./src/XML/contact.xml");
            @SuppressWarnings("static-access")
            OutputFormat format=new OutputFormat().createPrettyPrint();
            format.setEncoding("utf-8");
            XMLWriter writer=new XMLWriter(fos,format);
            writer.write(doc);
            writer.close();
        }
        /**
         * 表达式语法
         * 
         */
        public static void test() throws Exception{
            Document doc = new SAXReader().read(new File("./src/contact.xml"));
            String xpath = "";
            /**
             * 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标签
            
            @SuppressWarnings("unchecked")
            List<Node> list = doc.selectNodes(xpath);
            for (Node node : list) {
                System.out.println(node);
            }
        }
        /**
         * 模拟用户登录
         * @throws IOException 
         * @throws Exception 
         */
        public static void denglu() throws IOException, Exception{
            BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
            System.out.println("请输入用户名:");
            String name = reader.readLine();
            System.out.println("请输入密码:");
            String password = reader.readLine();
            
            //之后再Xml文档中查找是否有
            Document doc=new SAXReader().read(new File("./src/XML/user.xml"));
            Element user=(Element) doc.selectSingleNode("//user[@name='"+name+"' and @password='"+password+"']");
            if(user!=null){
                System.out.println("登录成功");
            }else{
                System.out.println("登录失败");
            }
        }
        /**
         * 读取Html文件
         * 练习:读取联系人的所有信息
         * 按照以下格式输出:
         *          编号:001 姓名:张三 性别:男 年龄:18 地址:xxxx 电话: xxxx
         *       编号:002 姓名:李四 性别:女 年龄:20 地址:xxxx 电话: xxxx
         *       ......
         */
        public static void readHtml() throws Exception{
            Document doc=new SAXReader().read(new File("./src/XML/persionList.html"));
            //读取所有tbody中的tr标签
            @SuppressWarnings("unchecked")
            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+"	姓名:"+name+"	性别:"+
                                            gender+"	年龄:"+
                                            age+"	地址:"+address+
                                            "	电话:"+phone);
                    }
        }
    View Code

        (三)SAX解析

          a.出现原因:因为DOM解析会一次将xml文档加载到内存中去,然后内存中的构建Document树,这样对内存要求比较高,不适合读取大容量的xml文件,容易导致内存溢出

          b.解析原理:加载一点,读取一点,处理一点,对内存要求比较低

          c.解析工具:内置再jdk中的org.xml.sax.*(Sun公司提供)

          d.核心API:SAXParser类:用于读取和解析xml文件对象

               parse(File f, DefaultHandler dh)方法: 解析xml文件

                  DefaultHandler: SAX事件处理程序。使用DefaultHandler的子类

          d.如何使用:

            1.创建SAXParser对象

              SAXParser parser=SAXParserFactory.newInstance().newSAXParser();

            2.调用parse方法

              parser.parse(new File("./src/contact.xml"), new MyDefaultHandler());}

               MyDefaultHandler()是DefaultHandler子类需要对这个重写方法达到操作xml文件的目的

            3.重写DefaultHandler子类

              void startDocument() : 在读到文档开始时调用

              void endDocument() :在读到文档结束时调用

              void startElement(String uri, String localName, String qName, Attributes attributes) :读到开始标签时调用

              void endElement(String uri, String localName, String qName) :读到结束标签时调用

              void characters(char[] ch, int start, int length) : 读到文本内容时调用

     例子:

    主函数

    public class SAX1 {
    
        public static void main(String[] args) throws Exception, SAXException {
            //创建SAXParser对象
            SAXParser parser=SAXParserFactory.newInstance().newSAXParser();
            //调用parse方法
            MyDefaultHandler2 handler=new MyDefaultHandler2();
            parser.parse(new File("./src/XML/contact.xml"),handler );
            String content=handler.getContent();
            System.out.println(content);
        }
    }
    View Code

    重写的DefaultHandler1子类

    public class MyDefaultHandler2 extends DefaultHandler{
        //存储xml文档信息
        private StringBuffer sb=new StringBuffer();
        //获取xml信息
        public String getContent(){
            return sb.toString();
        }
        /**
         * 开始标签时调用
         * @param qName: 表示开始标签的标签名
         * @param attributes: 表示开始标签内包含的属性列表
         */
        @Override
        public void startElement (String uri, String localName,
                String qName, Attributes attributes)
                        throws SAXException
        {
            sb.append("<"+qName);
            if(attributes!=null){
                for(int i=0;i<attributes.getLength();i++){
                    //获得属性名
                    String attrName=attributes.getQName(i);
                    //获得属性值
                    String attrValue=attributes.getValue(i);
                    sb.append(" "+attrName+"=""+attrValue+""");
                }
            }
            sb.append(">")    ;
    
        }
        /**
         * 结束标签时调用
         * @param qName: 结束标签的标签名称
         */
        @Override
         public void endElement (String uri, String localName, String qName)
                    throws SAXException
         {
            sb.append("</"+qName+">");
         }
        /**
         * 读到文本内容的时调用
         * @param ch: 表示当前读完的所有文本内容
         * @param start: 表示当前文本内容的开始位置
         * @param length: 表示当前文本内容的长度
         * char[](                                       张三              20)   100
         *                              98 2   
         */ 
        @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            //得到当前文本内容
            String content = new String(ch,start,length);
            sb.append(content);
        }
        /**
         * 结束文档时调用
         */
        @Override
        public void endDocument() throws SAXException {
        }
        
    }
    View Code

    重写DefaultHandler1子类

    public class MyDefaultHandler extends DefaultHandler{
        /**
         * 开始文档时调用
         */
        @Override
        public void startDocument()throws SAXException {
            System.out.println("MyDefaultHandler.startDocument()");
        }
        /**
         * 开始标签时调用
         * @param qName: 表示开始标签的标签名
         * @param attributes: 表示开始标签内包含的属性列表
         */
        @Override
        public void startElement (String uri, String localName,
                String qName, Attributes attributes)
                        throws SAXException
        {
            System.out.println("MyDefaultHandler.startElement()-->"+qName);
        }
        /**
         * 结束标签时调用
         * @param qName: 结束标签的标签名称
         */
        @Override
         public void endElement (String uri, String localName, String qName)
                    throws SAXException
         {
            System.out.println("MyDefaultHandler.endElement()-->"+qName);
         }
        /**
         * 读到文本内容的时调用
         * @param ch: 表示当前读完的所有文本内容
         * @param start: 表示当前文本内容的开始位置
         * @param length: 表示当前文本内容的长度
         * char[](                                       张三              20)   100
         *                              98 2   
         */ 
        @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            //得到当前文本内容
            String content = new String(ch,start,length);
            System.out.println("MyDefaultHandler.characters()-->"+content);
        }
        /**
         * 结束文档时调用
         */
        @Override
        public void endDocument() throws SAXException {
            System.out.println("MyDefaultHandler.endDocument()");
        }
        
    }
    View Code

        (四)DOM vs SAX解析

    DOM解析

    SAX解析

    原理: 一次性加载xml文档,不适合大容量的文件读取

    原理: 加载一点,读取一点,处理一点。适合大容量文件的读取

    DOM解析可以任意进行增删改成

    SAX解析只能读取

    DOM解析任意读取任何位置的数据,甚至往回读

    SAX解析只能从上往下,按顺序读取,不能往回读

    DOM解析面向对象的编程方法(NodeElementAttribute,Java开发者编码比较简单。

    SAX解析基于事件的编程方法。java开发编码相对复杂。

    2.XML约束

      一:约束技术:  

        DTD约束:语法相对简单,功能也相对简单。学习成本也低。

        Schema约束:语法相对复杂,功能也相对强大。学习成本相对高!!!(名称空间)

      二:DTD约束:

          导入:内部导入;外部导入

            外部导入:本地文件系统;<!DOCTYPE note SYSTEM "note.dtd">

                 公共的外部导入:<!DOCTYPE 根元素 PUBLIC "http:........">

          语法:

            约束标签:<!ELEMENT 元素名称 类别> 或 <!ELEMENT 元素名称 (元素内容)>

                类别:EMPTY:空标签;(#PCDATA)表示元素一定是普通字符(不能包含子标签);ANY:表示元素任意字符(可以包含子标签)

                元素内容:  

                    顺序问题:<!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,.....)> 按顺序出现子标签

                    次序问题:空:1次;+:至少1次;*:0~n次;?0~1次

            约束属性:<!ATTLIST 元素名称 属性名称 属性类型 默认值>

                默认类型:控制属性值的

                    CDATA :表示普通字符串

                    (en1|en2|..) 表示一定是任选其中的一个值

                    ID:表示在一个xml文档中该属性值必须唯一。值不能以数字开头

                默认值:#REQUIRED 属性值是必需的

                    #IMPLIED   属性不是必需的

                    #FIXED value 属性不是必须的,但属性值是固定的

    例子:

      <!ELEMENT note (from?,to+,heading*,body+)>
      <!ELEMENT to      EMPTY>
      <!ELEMENT from    (#PCDATA)>
      <!ELEMENT heading (#PCDATA)>
      <!ELEMENT body    (#PCDATA)>
      <!ATTLIST to id ID #REQUIRED>
    <?xml version="1.0"?>
    <!DOCTYPE note SYSTEM "note.dtd">
    <note>
      <from></from>
      <to id="a1"></to>
      <to id="a2"></to>
      <to id="a3"></to>
      <heading>Reminder</heading>
      <heading>Reminder</heading>
      <heading>Reminder</heading>
      <body>Don't forget me this weekend</body>
      <body>Don't forget me this weekend</body>
      <body>Don't forget me this weekend</body>
    </note>
    View Code

      三:Schema约束

       (一)使用它的原因

          a.支持数据类型b.是DTD的替代c.是用xml来编写之后处理Schema变得更加方便d.可保护数据通信e.可扩展

      (二)名称空间:告诉xml文档的哪个元素被哪个schema文档约束 在一个xml文档中,不同的标签可以受到不同的schema文档的约束。

           1)一个名称空间受到schema文档约束的情况

           2)多个名称空间受到多个schema文档约束的情况

           3)默认名称空间的情况

           4)没有名称空间的情况

      (三)使用方法

          http://www.w3school.com.cn/schema/schema_howto.asp

      (四)例子

    <?xml version="1.0" encoding="UTF-8"?>
    <itcast:书架 xmlns:itcast="http://www.itcast.cn"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.itcast.cn book.xsd">
        <itcast:>
            <itcast:书名>JavaScript网页开发</itcast:书名>
            <itcast:作者>张孝祥</itcast:作者>
            <itcast:售价>28</itcast:售价>
        </itcast:书>
    
    </itcast:书架>
    View Code
    <?xml version="1.0" encoding="UTF-8" ?> 
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
                          targetNamespace="http://www.itcast.cn"
                          elementFormDefault="qualified">
        <xs:element name='书架' >
            <xs:complexType>
                <xs:sequence maxOccurs='unbounded' >
                    <xs:element name='书' >
                        <xs:complexType>
                            <xs:sequence>
                                <xs:element name='书名' type='xs:string' />
                                <xs:element name='作者' type='xs:string' />
                                <xs:element name='售价' type='xs:integer' />
                            </xs:sequence>
                        </xs:complexType>
                    </xs:element>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    </xs:schema>
    View Code

      (五)注意:

        对Schema的编写我们可在eclipse中编写调到设计模式编写更方便

                  

  • 相关阅读:
    SVN合并时报错:Merge tracking not allowed with missing subtrees; try restoring these items
    The operation names in the portType match the method names in the SEI or Web service implementation class.
    原生java调用webservice的方法,不用生成客户端代码
    如何快速开发一个支持高效、高并发的分布式ID生成器
    分布式ID生成器解决方案
    高并发分布式系统中生成全局唯一Id汇总
    python接口自动化17-multipart/form-data表单提交
    httprunner学习25-文件上传multipart/form-data
    python测试开发django-72.删除表后如何重新生成表
    python测试开发django-71.自定义标签tag
  • 原文地址:https://www.cnblogs.com/xiaoping1993/p/xml.html
Copyright © 2020-2023  润新知