zoukankan      html  css  js  c++  java
  • XML

    1.什么是XML

    XML的作用:处理有关系的数据,它允许用户自定义标签,一个标签用于描述一段数据;一个标签可以分为开始标签和结束标签,在开始标签和结束标签之间,又可以使用其他标签描述其他数据,以此来实现数据关系的描述。

    2.XML常见应用

    • XML技术除了用于保存有关系的数据之外,它还经常用于软件配置文件,以描述程序模板之间的关系
    • 在一个软件系统中,为提高系统的灵活性,它所启动的模块通常由配置文件决定(例如一个软件在启动时,它需要启动A,B两个模块,而A,B这两个模块在启动时,又分别需要A1,A2和B1,B2模块的支持,为了准确描述这种关系,此时使用XML文件最为合适)
    <soft>
        <a>
            <a1></a1>
            <a2></a2>
        </a>
        <b>
            <b1></b1>
            <b2></b2>
        </b>
    </soft>

    3.XML语法

    1.文档声明

    在编写XML文档时,需要先使用文档声明,声明XML文档的类型

    固定格式为

    <?xml            ?>

    在空格里面写版本和编码格式<?xml和?>是固定格式,不能修改,中间连空格都不能有,要一模一样。

    注意:写的时候如果想用空格将内容隔开,只能用英文空格。

    标准写法:其中version代表版本,encoding代表编码,standalone代表文档是否独立(是否依赖别的文档)

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

    2.元素

    • XML元素指XML文件中出现的标签

        包含标签体:<a>javaweb</a>

        不含标签体:<a></a>(简写为<a/>)

    • 一个标签中也可以嵌套若干子标签。但所有标签必须合理的嵌套,绝对不允许交叉嵌套
    • 格式良好的XML文档必须有且仅有一个根标签,其他标签都是这个根标签的子孙标签
    • 对于XMl标签中出现的所有空格和换行,XML解析程序都会当作标签内容进行处理(所以在编写XML文件时,使用换行和缩进等方式来让原文件中的内容清晰可读的“良好”书写习惯可能要被迫改变)
    • 一个XML元素可以包含字母,数字以及其他一些可见字符,但是必须遵守下面一些规范

        区分大小写

        不能以数字或“_”开头

        不能以xml(XML或Xml等开头)

        不能包含空格

        名称中间不能包含冒号(:)

    3.属性

    • 一个标签可以有多个属性,每个属性都有它自己的名字和取值  
      <input name="text">
    • 属性值一定要用双引号或单引号引起来
    • 定义属性必须遵循和标签相同的命名规范
    • 在XML技术中,标签所代表的信息,也可以被改成用子元素的形式来描述
      <input>
          <name>text</name>
      </input>

    4.注释

    • XML文件中的注释采用:<!--注释-->
    • XML声明之前不能有注释
    • 注释不能嵌套

    5.CDATA区

    • 在编写XML文件时,有些内容可能不想让解析引擎解析执行,而是当作原始内容处理,遇到这种情况,可以把这些内容放在CDATA区里,对于CDATA区域的内容,XML解析程序不会处理,而是直接原封不动的输出
    • 语法:<![CDATA[内容]]>
      <![CDATA[
              <a>JavaWeb</a>
      ]]>

    6.转义字符

    • &lt; < 小于号 
    • &gt; > 大于号 
    • &amp; & 和 
    • &apos; ' 单引号 
    • &quot; " 双引号

    7.处理指令

    • 处理指令,简称PI。处理指令用来指挥解析引擎如何解析XML文档内容

      

    • 例如,在XML文档中可以使用xml-stylesheet指令,通知XML解析引擎,应用css文件现实XML文档内容。

      

      <?xml-stylesheet type="text/css" href="1.css" ?>
    • 处理指令必须以“<?”开头,以"?>"作为结尾,XML声明语句就是最常见的一种处理指令

    4.XML约束

    什么是XML约束:在XML技术里,可以编写一个文档来约束一个XML文档的书写规范,这称之为XML约束

    常用的约束技术:XML DTD,XML Schema

     

    1.DTD

    先举个例子写个book.dtd来约束book.xml

    book.dtd

    1 <!ELEMENT 书架 (书+)>
    2 <!ELEMENT 书 (书名,作者,售价)>
    3 <!ELEMENT 书名 (#PCDATA)>
    4 <!ELEMENT 作者 (#PCDATA)>
    5 <!ELEMENT 售价 (#PCDATA)>

    book.xml

     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 <!DOCTYPE 书架 SYSTEM "book.dtd">
     3 <书架>
     4     <>
     5         <书名>java就业培训教程</书名>
     6         <作者>张孝祥</作者>
     7         <售价>39.00元</售价>
     8     </>
     9     <>
    10         <书名>javaScript网页开发</书名>
    11         <作者>张孝详</作者>
    12         <售价>28.00元</售价>
    13     </>
    14 </书架>

    这样就约束了book.xml的书写,也就是书架里面只能有书,书必须有书名,作者,售价,而且顺序不能改变。

    2.DTD语法

    • 引用DTD约束

        当引用的文件在本地时,采用如下方式:

        <!DOCTYPE XML文档根节点 SYSTEM "DTD文件的URL">

        当引用的文件是一个公共的文件时,采用如下方法

        <!DOCTYPE XML文档根节点 PUBLIC "DTD名称" "DTD文件的URL">

    • 元素定义

        在DTD文档中使用ELEMENT声明一个XML元素,语法格式如下:

        <!ELEMENT 元素名称 元素类型>

        元素类型可以是元素内容,或类型,下面举例子

        元素类型为元素内容:<!ELEMENT 书 (书名,作者,售价)>

        元素类型为类型:<!ELEMENT 书名 (#PCDATA)>

        DTD规范定义了,EMPTY表示空元素,ANY表示元素内容为任意类型

        元素内容中可以用如下方式,描述内容的组成关系

        用逗号分隔,表示内容的出现顺序必须和声明时一致:<!ELEMENT 书 (书名,作者,售价)>

        用 | 分隔,表示任选其一,即多个只能出现一个:<!ELEMENT MYFILE (TITLE|AUTHOR|EMAIL)>

        在元素内容中也可以使用+,*,?等符号表示元素出现的次数

        +:一次或多次(书+)

        ?:0次或一次(书?)

        *:0次或多次(书*)

        也可以使用圆括号()批量设置

        <!ELEMENT MYFILE (TITLE*,AUTHOR?,EMALL)* | COMMENT>

    • 属性定义

        XML文档中的标签属性需通过ATTLIST为其设置属性

        语法格式:

        <!ATTLIST 元素名

              属性名1 属性值类型 设置说明

              属性名2 属性值类型 设置说明

              ........

        >

        属性声明举例:

        <! ATTLIST 商品

          类别 CDATA #REQUIRED (必须属性)

          颜色 CDATA #IMPLIED  (可选属性)

        >

        对于XML文件

        <商品 类别=“服装” 颜色=“黄色”></商品>

        <商品 类别=“面包”></商品>

        设置说明:

        #REQUIRED:必须设置改属性

        #IMPLIED:可以设置也可以不设置

        #FIXED:说明该属性的取值固定为一个值,在XML文件中不能为该属性设置其他值。但需要为

        该属性提供这个值

        直接使用默认值:在XML中可以设置该值也可以不设置该属性值。若没设置则使用默认值 

        常用属性值类型

        CDATA

        ENUMERATED

        ID(表示属性的设置值为一唯一值,ID属性的值只能由字母,下划线开始,不能出现空白符)

        ENTITY(实体:用于为一段内容创建一个别名,以后在XML文档中就可以使用别名引用这段内容)

          在DTD中定义实体要用<!ENTITY  >语句

          实体可分为两种类型:引用实体和参数实体

             引用实体:主要在XML文档中被应用

             语法格式:<!ENTITY 实体名称 “实体内容”>:直接转变成实体内容

             引用方法:&实体名称 

             举例:<!ENTITY copyright "l am a programmer">    &copyright  

             -------------------------------------------------------------------------------

             参数实体:被DTD文件自身使用

             语法格式:<!ENTITY % 实体名称 “实体内容”>

             引用方法:%实体名称

             举例说明:<!ENTITY % TAG_NAMES "姓名 | EMALL | 电话 | 地址">

                  <!ELEMENT 个人信息 (%TAG_NAMES | 生日)>

                  <!ELEMENT 客户信息 (%TAG_NAMES | 公司名)>  

    5.XML编程(CRUD)

    XML解析方式分为两种:dom和sax

      dom:(Document Object Model)是W3C组织推荐的解析XML的一种方式

         sax:(Simple API for XML)不是官方标准,但它是XML社区事实上的标准,几乎所有的XML解析器

      都支持它

    dom和sax解析方法的区别

      1.dom解析的优点是对文档crud比较方便,缺点就是占用内存比较大(所有元素全部在内存中生成相应的对象)

      2.sax解析的优点是占用内存少,解析速度快,缺点是只适合做文档的读取,不适合做文档的crud(一层一层的解析)

    XML解析开发包

      Jaxp(sun),Jdom,dom4j

    Jaxp

    • 是J2SE的一部分,它由javax.xml,org.w3c.dom,org.xml.parsers包及其子包组成
    • 在javax.xml.parsers包中,定义了几个工厂类,程序员调用这些工厂类,可以得到xml文档的DOM

       或SAX的解析器,从而实现对xml文档的解析

    使用Jaxp进行DOM解析:javax.xml.parsers包中的DocumentBuilderFactory用于创建DOM模式的解析器对象,DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance方法,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回

    例子:

            //1.创建工厂
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            //2.得到dom解析器
            DocumentBuilder db = factory.newDocumentBuilder();
            //3.解析xml文档,得到代表文档的document
            Document d = db.parse("src/book.xml");

    再用Junit写一些测试Demo

    先贴要解析的xml源码

     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 <!DOCTYPE 书架 SYSTEM "book.dtd">
     3 <书架>
     4     <>
     5         <书名 name="Hello">java就业培训教程</书名>
     6         <作者>张孝祥</作者>
     7         <售价>39.00元</售价>
     8     </>
     9     <>
    10         <书名 name="JavaWeb">javaScript网页开发</书名>
    11         <作者>张孝详</作者>
    12         <售价>28.00元</售价>
    13     </>
    14 </书架>

    测试代码

     1     @Test
     2     public void test1() throws Exception{
     3         
     4         //创建工厂
     5         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
     6         //得到dom解析器
     7         DocumentBuilder db = factory.newDocumentBuilder();
     8         //解析xml文档,得到代表文档的document
     9         Document d = db.parse("src/book.xml");
    10         //获得标签名为书名的对象集合
    11         NodeList nlist = d.getElementsByTagName("书名");
    12         //拿到集合里面的节点对象
    13         Node n1 = nlist.item(0);
    14         Node n2 = nlist.item(1);
    15         //得到节点的内容
    16         String s1 = n1.getTextContent();
    17         String s2 = n2.getTextContent();
    18         System.out.println(s1);
    19         System.out.println(s2);
    20         
    21     }

    结果如下:

    java就业培训教程
    javaScript网页开发

    测试代码二(获得所有标签的名字)

     1     @Test
     2     public void test2() throws Exception{
     3         
     4         // 创建工厂
     5         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
     6         // 得到dom解析器
     7         DocumentBuilder db = factory.newDocumentBuilder();
     8         // 解析xml文档,得到代表文档的document
     9         Document d = db.parse("src/book.xml");
    10         //得到根节点
    11         NodeList nlist = d.getElementsByTagName("书架");
    12         Node root = nlist.item(0);
    13         
    14         list(root);
    15         
    16     }    
    17     
    18     public void list(Node root){
    19         if(root instanceof Element){
    20         System.out.println(root.getNodeName());
    21           
    22         NodeList nlist = root.getChildNodes();
    23         
    24         for(int i=0; i<nlist.getLength(); i++){
    25             
    26             Node child = nlist.item(i);
    27             list(child);
    28         
    29         }
    30         }
    31     }

    Junit测试结果

    1 书架
    2 3 书名
    4 作者
    5 售价
    6 7 书名
    8 作者
    9 售价

    得到属性名的测试

     1     @Test
     2     public void test3() throws Exception{
     3         
     4         // 创建工厂
     5         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
     6         // 得到dom解析器
     7         DocumentBuilder db = factory.newDocumentBuilder();
     8         // 解析xml文档,得到代表文档的document
     9         Document d = db.parse("src/book.xml");
    10         
    11         NodeList nlist = d.getElementsByTagName("书名");
    12         
    13         Node n = nlist.item(0);
    14         
    15         Element e = (Element) n;
    16         String str = e.getAttribute("name");
    17         System.out.println(str);
    18     }

    测试结果得到hello

    上面的操作都只是查,没有对xml进行修改,如果需要对xml进行修改,我们需要把在内存中修改后的Document对象重新写入硬盘中原来的xml文件中,从而达到修改xml文件的效果。

    那么我们就需要用到更新XML文档的包了

    •   javax.xml.transform包中的Teansformer类用于把代表XML文件的Document转换为某种格式后

         进行输出,可以把Document对象又重新写入一个XML文件中

    •   Transformer类通过transform方法完成转换操作,该方法接受一个源和一个目的地,我们可以

            通过javax.xml.transform.dom.DOMSource类来关联要转换的document对象,用

         javax.xml.transform.stream.StreamResult对象来表示数据的目的地

    •      Transformer对象通过TransformerFactory获得

     举例说明

      1     @Test
      2     public void test4() throws Exception{
      3         
      4         // 创建工厂
      5         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      6         // 得到dom解析器
      7         DocumentBuilder db = factory.newDocumentBuilder();
      8         // 解析xml文档,得到代表文档的document
      9         Document d = db.parse("src/book.xml");
     10         // 创建节点
     11         Element e = d.createElement("售价");
     12         e.setTextContent("100元");
     13         //把节点挂到第一本书
     14         Node node = d.getElementsByTagName("书").item(0);
     15         node.appendChild(e);
     16         //把更新后的内存写回xml文档
     17         //我们这里只是把内存中的代表xml对象的那个数据修改了,并没有把这个写进硬盘
     18         //所以原来在硬盘里面的xml文件并没有被修改,所以我们需要把修改后的对象写入
     19         //硬盘中,得到修改后的xml文件
     20         TransformerFactory tffactory = TransformerFactory.newInstance();
     21         Transformer tf = tffactory.newTransformer();
     22         tf.transform(new DOMSource(d), new StreamResult(new FileOutputStream("src/book.xml")));
     23         
     24         
     25     }
     26     
     27     @Test
     28     //向文档中指定位置插入数据
     29     public void test5() throws Exception{
     30 
     31         // 创建工厂
     32         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
     33         // 得到dom解析器
     34         DocumentBuilder db = factory.newDocumentBuilder();
     35         // 解析xml文档,得到代表文档的document
     36         Document d = db.parse("src/book.xml");
     37         // 创建节点
     38         Element e = d.createElement("售价");
     39         e.setTextContent("100元");
     40         //得到参考节点
     41         Node node2 = d.getElementsByTagName("售价").item(0);
     42         //得到要插子节点的节点
     43         Node node = d.getElementsByTagName("书").item(0);
     44         //向指定位置插入节点
     45         node.insertBefore(e, node2);
     46         //把更新后的内存写回xml文档
     47         //我们这里只是把内存中的代表xml对象的那个数据修改了,并没有把这个写进硬盘
     48         //所以原来在硬盘里面的xml文件并没有被修改,所以我们需要把修改后的对象写入
     49         //硬盘中,得到修改后的xml文件
     50         TransformerFactory tffactory = TransformerFactory.newInstance();
     51         Transformer tf = tffactory.newTransformer();
     52         tf.transform(new DOMSource(d), new StreamResult(new FileOutputStream("src/book.xml")));
     53         
     54 
     55     }
     56     
     57     @Test
     58     //向指定节点添加属性
     59     public void test6() throws Exception{
     60         
     61         // 创建工厂
     62         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
     63         // 得到dom解析器
     64         DocumentBuilder db = factory.newDocumentBuilder();
     65         // 解析xml文档,得到代表文档的document
     66         Document d = db.parse("src/book.xml");
     67         // 得到书名节点
     68         Element bookName = (Element) d.getElementsByTagName("书名").item(0);
     69         bookName.setAttribute("name", "修改后的名字");
     70         //更新内存
     71         TransformerFactory tffactory = TransformerFactory.newInstance();
     72         Transformer tf = tffactory.newTransformer();
     73         tf.transform(new DOMSource(d), new StreamResult(new FileOutputStream("src/book.xml")));
     74         
     75         
     76         
     77     }
     78     
     79     @Test
     80     //删除节点
     81     public void test7() throws Exception{
     82         
     83         // 创建工厂
     84         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
     85         // 得到dom解析器
     86         DocumentBuilder db = factory.newDocumentBuilder();
     87         // 解析xml文档,得到代表文档的document
     88         Document d = db.parse("src/book.xml");
     89         //得到要删除的节点
     90         Element eSon = (Element) d.getElementsByTagName("售价").item(0);
     91         //得到要删除节点的父节点
     92         Element eFather = (Element) d.getElementsByTagName("书").item(0);
     93         //调用父节点的方法删除子节点
     94         eFather.removeChild(eSon);
     95         //更新内存
     96         TransformerFactory tffactory = TransformerFactory.newInstance();
     97         Transformer tf = tffactory.newTransformer();
     98         tf.transform(new DOMSource(d), new StreamResult(new FileOutputStream("src/book.xml")));
     99         
    100     }
    101     
    102     @Test
    103     //删除节点(方法二)
    104     public void test8() throws Exception{
    105         
    106         // 创建工厂
    107         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    108         // 得到dom解析器
    109         DocumentBuilder db = factory.newDocumentBuilder();
    110         // 解析xml文档,得到代表文档的document
    111         Document d = db.parse("src/book.xml");
    112         //得到要删除的节点
    113         Element eSon = (Element) d.getElementsByTagName("售价").item(0);
    114         eSon.getParentNode().removeChild(eSon);
    115         
    116         //更新内存
    117         TransformerFactory tffactory = TransformerFactory.newInstance();
    118         Transformer tf = tffactory.newTransformer();
    119         tf.transform(new DOMSource(d), new StreamResult(new FileOutputStream("src/book.xml")));
    120         
    121     }
    122     
    123     @Test
    124     //更新价格
    125     public void test9() throws Exception{
    126         
    127         // 创建工厂
    128         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    129         // 得到dom解析器
    130         DocumentBuilder db = factory.newDocumentBuilder();
    131         // 解析xml文档,得到代表文档的document
    132         Document d = db.parse("src/book.xml");
    133         //得到要修改的售价节点
    134         Element e = (Element) d.getElementsByTagName("售价").item(0);
    135         e.setTextContent("10000元");
    136         
    137         //更新内存
    138         TransformerFactory tffactory = TransformerFactory.newInstance();
    139         Transformer tf = tffactory.newTransformer();
    140         tf.transform(new DOMSource(d), new StreamResult(new FileOutputStream("src/book.xml")));
    141         
    142     }

     sax解析:允许我们在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才能对文档进行操作(一层一层的解析)

    • sax解析采用的是事件处理的方式解析XML文件,利用SAX解析XML文档,涉及两个部分,解析器和处理器
    • 解析器:可以使用JAXP的API创建,创建出SAX解析器后,就可以以指定解析器去解析某个XML文档
    • 解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器
    • 事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理

    代码实例

    package day0503;
    
    
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    
    import org.xml.sax.Attributes;
    import org.xml.sax.ContentHandler;
    import org.xml.sax.Locator;
    import org.xml.sax.SAXException;
    import org.xml.sax.XMLReader;
    
    
    
    public class Demo1{
        
        public static void main(String[] args) throws Exception{
            
            //1.创建解析工厂
            SAXParserFactory factory = SAXParserFactory.newInstance();
            //2.得到解析器
            SAXParser sp = factory.newSAXParser();
            //3.得到读取器
            XMLReader reader = sp.getXMLReader();
            //4.设置内容处理器
            reader.setContentHandler(new ListHandler());
            //5.读取xml文档内容
            reader.parse("src/book.xml");
        }
        
    }
    
    //内容处理器
    class ListHandler implements ContentHandler{
    
        @Override
        public void setDocumentLocator(Locator locator) {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void startDocument() throws SAXException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void endDocument() throws SAXException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void startPrefixMapping(String prefix, String uri) throws SAXException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void endPrefixMapping(String prefix) throws SAXException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
            // TODO Auto-generated method stub
            System.out.println("<" + qName + ">");
            for(int i=0;atts!=null&&i<atts.getLength(); i++){
                
                String attName = atts.getQName(i);
                String attValue = atts.getValue(i);
                System.out.println(attName + "=" + attValue);
                
            }
        }
    
        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            // TODO Auto-generated method stub
            System.out.println("<" + qName + ">");
    
        }
    
        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            // TODO Auto-generated method stub
            System.out.println(new String(ch,start,length));
        }
    
        @Override
        public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void processingInstruction(String target, String data) throws SAXException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void skippedEntity(String name) throws SAXException {
            // TODO Auto-generated method stub
            
        }
    
    }

    使用SAX解析封装对象

     1 package day0503;
     2 
     3 import java.io.IOException;
     4 import java.util.ArrayList;
     5 import java.util.List;
     6 
     7 import javax.xml.parsers.ParserConfigurationException;
     8 import javax.xml.parsers.SAXParser;
     9 import javax.xml.parsers.SAXParserFactory;
    10 
    11 import org.xml.sax.Attributes;
    12 import org.xml.sax.SAXException;
    13 import org.xml.sax.XMLReader;
    14 import org.xml.sax.helpers.DefaultHandler;
    15 
    16 public class Demo3 {
    17 
    18     public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
    19         // TODO Auto-generated method stub
    20 
    21         //1.创建解析工厂
    22         SAXParserFactory factory = SAXParserFactory.newInstance();
    23         //2.得到解析器
    24         SAXParser sp = factory.newSAXParser();
    25         //3.得到读取器
    26         XMLReader reader = sp.getXMLReader();
    27         //4.设置内容处理器
    28         BeanListHandler handle = new BeanListHandler();
    29         reader.setContentHandler(handle);
    30         //5.读取xml文档内容
    31         reader.parse("src/book.xml");
    32         
    33         List<Book> list = handle.getList();
    34         System.out.println(list);
    35     }
    36 
    37 }
    38 
    39 //把xml文档中的每一本书封装到一个book对象,并把多个book对象放在一个list集合中返回
    40 class BeanListHandler extends DefaultHandler{
    41 
    42     private List list = new ArrayList();
    43     private String currentTag;
    44     private Book book;
    45     
    46     @Override
    47     public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    48 
    49         currentTag = qName;
    50         if("书".equals(qName)){
    51             book = new Book();
    52             
    53         }
    54         
    55     }
    56     
    57     @Override
    58     public void characters(char[] ch, int start, int length) throws SAXException {
    59         
    60         if("书名".equals(currentTag)){
    61             String name = new String(ch,start,length);
    62             book.setName(name);
    63         }
    64         if("作者".equals(currentTag)){
    65             String author = new String(ch,start,length);
    66             book.setAuthor(author);
    67         }
    68         if("价格".equals(currentTag)){
    69             String price = new String(ch,start,length);
    70             book.setPrice(price);
    71         }
    72         
    73     }
    74 
    75     @Override
    76     public void endElement(String uri, String localName, String qName) throws SAXException {
    77         
    78         currentTag = null;
    79         if("书".equals(qName)){
    80             list.add(book);
    81             book = null;
    82         }
    83         
    84     }
    85     
    86     public List<Book> getList() {
    87         return list;
    88     }
    89 
    90 }

    Dom4j解析XML

    使用Dom4j开发,需要下载dom4j相应的jar文件

    使用说明:https://dom4j.github.io/

    实例代码(有乱码问题)

     1 package day0506;
     2 
     3 import java.io.File;
     4 import java.io.FileWriter;
     5 import java.io.IOException;
     6 
     7 import org.dom4j.Document;
     8 import org.dom4j.DocumentException;
     9 import org.dom4j.Element;
    10 import org.dom4j.io.SAXReader;
    11 import org.dom4j.io.XMLWriter;
    12 import org.junit.Test;
    13 
    14 public class Demo1111 {
    15     
    16     @Test
    17     public void test1() throws DocumentException{
    18         
    19         SAXReader reader = new SAXReader();
    20         Document document = reader.read(new File("src/book.xml"));
    21         Element root = document.getRootElement();
    22         Element book = root.elements("书").get(1);
    23         String value = book.element("书名").getText();
    24         System.out.println(value);
    25         
    26     }
    27     
    28     @Test
    29     public void test2() throws DocumentException, IOException{
    30         
    31         SAXReader reader = new SAXReader();
    32         Document document = reader.read(new File("src/book.xml"));
    33         Element book = document.getRootElement().element("书");
    34         book.addElement("售价").setText("209元");
    35         //更新内存
    36          XMLWriter writer = new XMLWriter(new FileWriter("src/book.xml"));
    37          writer.write( document );
    38          writer.close();
    39          //乱码
    40     }
    41     
    42 }

    为什么会出现乱码呢?那是因为java的io流默认的字符编码和xml的字符编码不一致,那我们就需要使用

    可以指定字符编码io流了

    我们查一下api就可以知道可以使用:OutputStreamWriter(OutputStream out, CharsetEncoder enc)

    创建一个使用给定字符集编码器的OutputStreamWriter。这样问题就被解决了

     解决乱码的方案就是设置一个编码转换器

    1 OutputFormat format = OutputFormat.createPrettyPrint();
    2 format.setEncoding("UTF-8");
    3 XMLWriter writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream("src/book.xml"), "UTF-8"), format);
    4 writer.write(document);
    5 writer.close();

    使用XPath提取xml文档数据

    XPath使用很方便,要使用的时候查官方文档就行,而且官方文档有中文版的

    下面给出实例代码:

    public class Demo2 {
        
        @Test
        public void test1() throws DocumentException{
            
            SAXReader reader = new SAXReader();
            Document document = reader.read(new File("src/book.xml"));
            
            String s = document.selectSingleNode("//作者").getText();
            System.out.println(s);
        }
        
    }
    View Code

    使用XPath可以非常方便的提取到想要的节点。

    XML Schema

    XML Schema也是一种用于定义和描述XML文档结构与内容的模式语言,其出现是为了克服DTD的局限性

    XML Schema VS DTD:

    • XML Schema符合XML语法结构。
    • DOM,SAX等XML API很容易解析出XML Schema文档中的内容。                 
    • XML Schema对名称空间支持得非常好
    • XML Schema比XML DTD支持更多得数据类型,并支持用户自定义新的数据类型。
    • XML Schema定义约束能力非常强大,可以对XML实例文档作出细致得语义限制
    • XML Schema不能像DTD一样定义实体,比DTD更复杂,但Xml Schema现在已是w3c组织得标准,它正逐步取代DTD

     XML Schema约束快速入门

    •  XMLSchema文件自身就是一个XML文件,但它得扩展名通常为xsd。
    • 一个XML Schema文档通常称之为模式文档(约束文档),遵循这个文档书写的xml文件称之为实例文档
    • 和XML文件一样,一个XML Schema文档也必须有一个根结点,但这个根节点的名称为Schema
    • 编写一个XML Schema约束文档后,通常需要把这个文件中声明的元素绑定到一个URI地址上,在XML Schema技术中有一个专业术语来描述这个过程,即把XML Schema文档声明的元素绑定到一个名称空间上,以后XML文件就可以通过这个URI(即名称空间)来告诉解析引擎,XML文档中编写的元素来自哪里,被谁约束。

     使用教程:http://www.w3school.com.cn/schema/index.asp

  • 相关阅读:
    关于Action中ValidateXXX方法校验一次失败后\导致以后一直返回input视图的情况
    but has failed to stop it. This is very likely to create a memory leak(c3p0在Spring管理中,连接未关闭导致的内存溢出)
    个人学习笔记MyBatis的搭建及第一个程序
    Hibernate学习笔记环境搭建及运行
    个人学习笔记MyBatis官方推荐DAO开发方案
    个人笔记struts2对Action的权限拦截
    hession
    正向代理,反向代理
    path,classpath
    session
  • 原文地址:https://www.cnblogs.com/Vamps0911/p/10778405.html
Copyright © 2011-2022 走看看