xml

XML概述
    XML 指可扩展标记语言(EXtensible Markup Language) 
    XML 是一种标记语言,很类似 HTML 
    XML 和 HTML都是从SGML衍生出来的
    XML 的设计宗旨是传输数据,而非显示数据 
    XML 标签没有被预定义。需要自行定义标签。 
    XML 文件后缀名为xml
    w3cshool是很好的教程,可去学习



XML和HTML的关系
    XML 和 HTML 为不同的目的而设计:
        XML 被设计为传输和存储数据,其焦点是数据的内容。
        HTML 被设计用来显示数据,其焦点是数据的外观。
        HTML 旨在显示信息,而 XML 旨在传输信息。
    XML 标签没有被预定义。需要自行定义标签。
    HTML 是语法不严格的,XML是语法严格的(不能有任何错误)



XML的特点
    XML 是不作为的,即 XML 不会做任何事情。只是提供了一种独立于软件和硬件的数据存储方法。需要自己对XML进行解析并操作
    XML 仅仅是纯文本,标签都是自定义的.有能力处理纯文本的软件都可以处理 XML。(跨平台,跨语言)
    XML 被设计用来结构化、存储以及传输信息。
    XML 的主要用途:配置文件,存储数据



树结构
    XML 文档形成了一种树结构,它从“根部”开始,然后扩展到“枝叶”。
    XML 文档必须包含根元素。该元素是所有其他元素的父元素。
    父、子以及同胞等术语用于描述元素之间的关系。父元素拥有子元素。相同层级上的子元素成为同胞(兄弟或姐妹)。
    所有元素均可拥有文本内容和属性(类似 HTML 中)。



XML语法规则
    XML是语法严格的(不能有任何错误)
    XML 文档必须有根元素
    XML 元素必须有关闭标签
    XML 标签对大小写敏感
    XML 必须正确地嵌套
    XML 的属性值必须加引号



XML语法
    * 文档声明 
        位置:xml文档第一行
        格式:<?xml version="1.0" encoding="编码" ?>
            version : 指xml版本,目前只有1.0
            encoding : 文档内容编码(字符集)
    * 元素
        XML元素就是XML中出现的标签
        书写方式: <a>内容</a>  |  <a />
        xml解析时会将空格和回车换行当做内容处理(和html不一样)
        元素可包含其他元素、文本或者两者的混合物。元素也可以拥有属性。
        XML元素命名规则:
            名称可以含字母、数字以及其他的字符 
            名称不能以数字或者标点符号开始 
            名称不能以字符 “xml”(或者 XML、Xml)开始 
            名称不能包含空格
            尽量避免 - . :
    * 属性
        标签名称之后,使用空格分隔,属性名="属性值" ,属性值需要引号括住(一般使用双引号)
    * 注释  
        格式:<!-- 注释内容 -->
        注意:注释内容中,不能使用"--"特殊字符
    * 字符实体
        * xml存在特殊的字符,xml语法中所使用的字符
            <   &lt;
            >   &gt;
            &   &amp;
    * CDATA区
        * 特殊的区域可以书写任意字符
        格式:<![CDATA[ 任意内容 ]]>
    * 处理指令(processing instruction) (了解)
        * 指挥解析引擎如何解析XML文档内容
        位置:文档声明下方
        例如,通知XML解析引擎,使用css文件显示xml文档内容:<?xml-stylesheet type="text/css" href="1.css"?>



XML中文乱码
    * 文件编码
        可以通过记事本打开,通过 文件-->另存为-->编码 查看(windows 默认编码GBK)
    * 内容编码
        由文档声明的encoding属性来确定,浏览器根据此编码解析xml文件
    * 两者统一即可解决中文乱码



约束
    * 约束,规定如何编写xml内容
    * 分类:DTD、schema



XML DTD
    * DTD 的作用是定义 XML 文档的结构。它使用一系列合法的元素来定义文档结构
    * 文件扩展名:dtd
    * 为XML文档添加DTD约束的方式
        * 内部关联
            将DTD约束内容编写在xml文档
            格式:在文档声明下添加<!DOCTYPE 根元素 [约束内容]>
        * 外部关联
            将DTD约束内容编写在DTD文档中,然后引入外部DTD文档
            格式:在文档声明下添加<!DOCTYPE 根元素 SYSTEM "DTD文件路径">
        * 公共关联
            DTD文档在互联网上,框架使用的DTD都是公共关联
            格式:在文档声明下添加<!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD在web地址URL">
    * DTD语法
        * 从根元素开始,从上往下进行约束
        * 元素约束
            * 格式:<!ELEMENT 元素名称 内容约束>
                内容约束:符号、类型
                    符号
                        ?       --> 0或1个
                        *       --> 0到多个
                        +       --> 一个或多个
                        ,       --> 多个元素必须顺序使用
                        |       --> 多个元素选择一个
                        ()      --> 分组
                    类型
                        (#PCDATA)   -->标签体必须是文本,不能有其他标签
                        EMPTY       -->不能有标签体,即不能有内容
            * 示例:
                <!ELEMENT books (book+)>
                <!ELEMENT book (title?,price*,author)>
                <!ELEMENT title (#PCDATA)>
                <!ELEMENT price (#PCDATA)>
                <!ELEMENT author EMPTY>
        * 属性约束
            * 格式:<!ATTLIST 元素名称 属性约束 属性约束...>
                属性约束: 属性名 属性类型 约束
                    属性类型:
                        CDATA   --> 文本
                        (a|b|c) --> 多选一
                        ID      --> 唯一标识,不能以数字开头,不能为空
                        IDREF   --> ID引用
                    约束:
                        #REQUIRED       -->必须 required
                        #IMPLIED        -->可选 implied
                        #FIXED value    -->固定一个值 value为具体的值
                        默认值
            * 示例:
                <!ATTLIST book 
                  id ID #REQUIRED
                  lang CDATA #IMPLIED
                  city (北京|上海|广州) "北京"
                  company CDATA #FIXED "itcast">
                也可以分开写,如
                    <!ATTLIST book id ID #REQUIRED>
                    <!ATTLIST book lang CDATA #IMPLIED>
        * 实体
            * 相当于变量
            * 引用实体(一般实体):
                在DTD中定义,在xml中使用
                DTD定义:<!ENTITY 实体名称 "内容">
                xml使用:&实体名称;
            * 参数实体:
                在DTD中定义,在DTD中使用
                DTD定义:<!ENTITY % 实体名称 "内容">
                DTD使用:%实体名称;
            * 示例:
                在DTD定义实体
                    <!--引用实体-->
                    <!ENTITY info "公司信息提示">
                    <!--参数实体-->
                    <!ENTITY % part "title?,price*">
                在DTD中使用参数实体
                    <!ELEMENT book (%part;,author)>
                在xml中使用引用实体
                    <title>&info;</title>
    * 完整示例:
        books2.dtd
            <?xml version="1.0" encoding="UTF-8"?>
            <!--根元素-->
            <!ELEMENT books (book+)>
            <!ELEMENT book (title?,price*;,author)>
            <!ELEMENT title (#PCDATA)>
            <!ELEMENT price (#PCDATA)>
            <!ELEMENT author EMPTY>
            <!-- 给book添加属性-->
            <!ATTLIST book 
              id ID #REQUIRED
              lang CDATA #IMPLIED
              city (北京|上海|广州) "北京"
              company CDATA #FIXED "itcast"
            >
        books2.xml
            <?xml version="1.0" encoding="UTF-8"?>
            <!DOCTYPE books SYSTEM "books2.dtd">
            <books>
                <book id="b001" lang="cn" city="上海">
                    <title></title>
                    <price>abc</price>
                    <price></price>
                    <author />
                </book>
            </books>



XML Schema(不要求会写,要求能看懂)
    * XML Schema 是新的xml约束(比DTD复杂,比DTD强大)
    * schema文档本身就是xml
    * 文件扩展名:xsd(XML Schema Definition)
    * 命名空间(namespace):
        将schema文档中元素和属性,与URL进行绑定,用来处理名字的冲突。相当于java中的包
    * 创建schema文件
        <?xml version="1.0" encoding="UTF-8"?>
        <schema xmlns="http://www.w3.org/2001/XMLSchema" 
            targetNamespace="http://www.example.org/books" 
            xmlns:tns="http://www.example.org/books" 
            elementFormDefault="qualified">
        </schema>
        说明:
            schema 为根元素,固定
            xmlns="http://www.w3.org/2001/XMLSchema"
                规定默认的命名空间,没有前缀的标签默认来自于此命名空间(如根标签schema).后面的命名空间规定了schema文档的格式(此命名空间自动引入)
            targetNamespace="http://www.example.org/books" 
                给当前schema文档定义命名空间,可以给别人使用.要求:全球唯一
            xmlns:tns="http://www.example.org/books" 
                为命名空间指定前缀,前缀为tns.
            elementFormDefault="qualified"
                指出任何 XML 实例文档所使用的且在此 schema 中声明过的元素必须被命名空间限定。
    * 在xml中使用Schema约束
        <?xml version="1.0" encoding="UTF-8"?>
        <books xmlns="http://www.example.org/books"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.example.org/books books.xsd">
        </books>
        说明:
            books 为根元素
            xmlns="http://www.example.org/books"
                规定默认的命名空间,没有前缀的标签默认来自于此命名空间(如根标签books).这个命名空间需要在下面引入
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                为命名空间指定前缀,前缀为xsi,后面的命名空间的作用是获取schema文档实例,引入后才可以使用schemaLocation属性(此命名空间自动引入)
            xsi:schemaLocation="http://www.example.org/books books.xsd"
                确定xsd文件位置,需要 目标文件命名空间 和 xsd文件路径.可以有多个,用空格或换行隔开
    * 小结
        targetNamespace : 在xsd文件中使用,用来指定命名空间,即url
        xsi:schemaLocation : 在xml文件中使用,用来引入其他xsd文件,包括命名空间和文件位置
        xmlns : 定义默认命名空间
        xmlns:前缀 : 为命名空间指定前缀
        注意:schemaLocation属性在w3c的一个命名空间中,所以要先添加 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    * schema示例:
        books2.xsd
            <?xml version="1.0" encoding="UTF-8"?>
            <schema xmlns="http://www.w3.org/2001/XMLSchema" 
                targetNamespace="http://www.example.org/books2"
                xmlns:tns="http://www.example.org/books2" 
                elementFormDefault="qualified">
                
                <!-- 1 确定根元素 -->
                <element name="books">
                    <!-- 2 确定元素成员是否复杂
                            <simpleType>    简单类型,具有简单类型的的元素只能包含字符数据,不能包含子元素,也不能有属性
                            <complexType>   复杂类型,具有复杂类型的元素可以有子元素和属性
                         3 确定元素成员出场顺序
                            <sequence> 顺序 ##>等价于dtd ,
                            <choice> 选择       ##> 等价于 dtd |
                            <all>   任意
                                minOccurs 最小出现次数,默认值1
                                maxOccurs 最大出现次数,默认值1
                                minOccurs=0 , maxOccurs=1           等价于 ?
                                minOccurs=1 , maxOccurs=unbounded   等价于 +
                                minOccurs=0 , maxOccurs=unbounded   等价于 *
                     -->
                    <complexType>
                        <sequence minOccurs="1" maxOccurs="unbounded">
                            <element name="book">
                                <complexType>
                                    <sequence>
                                        <element name="title" type="string"></element>
                                        <element name="price">
                                            <complexType>
                                                <simpleContent>
                                                    <extension base="int">
                                                        <attribute name="unit" use="required"></attribute>
                                                    </extension>
                                                </simpleContent>
                                            </complexType>
                                        </element>
                                    </sequence>
                                    <!-- 确定属性 
                                        optional 表示可选
                                        required 表示必须
                                    -->
                                    <attribute name="id" use="required" type="ID"></attribute>
                                </complexType>
                            </element>
                        </sequence>
                    </complexType>
                </element>
            </schema>
        books2.xml
            <?xml version="1.0" encoding="UTF-8"?>
            <books xmlns="http://www.example.org/books2"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://www.example.org/books2 books2.xsd">
                <book id="b001">
                    <title></title>
                    <price unit="元">123</price>
                </book>
                <book id="b002">
                    <title></title>
                    <price unit="美元">123</price> <!--带属性和标签体的标签-->
                </book>
            </books>



XML解析
    * 解析方式:DOM 和 SAX
        * DOM方式:将整个文档加载到内存,获得一个Document对象,根据Document对象操作
            w3c推出规范
            优点:可完成增删改查操作
            缺点:不易操作大文件,比较占用内存,极易出现内存溢出
        * SAX方式:逐行解析,事件驱动
            xml社区推出,民间
            优点:占用内存小
            缺点:只能读取,不能修改
    * xml解析器:根据不同解析方式完成xml解析。操作比较繁琐
    * xml解析开发包:根据解析器提供一些容易操作的api.
        * jaxp -- java提供(Java API for XML Processing)
        * dom4j -- 第三方提供,比较简单



jaxp--dom方式解析
    * javax.xml.parsers包
    * 代码示例:
        在项目根目录下创建books.xml
            <?xml version="1.0" encoding="UTF-8"?>
            <books> 
              <book id="b001"> 
                <title>java编程思想</title>  
                <price>68</price> 
              </book>
              <book id="b002">
                <title>数据结构</title>
                <price>32</price> 
              </book> 
            </books>
        java代码
            package test;
            import java.io.File;
            import javax.xml.parsers.*;
            import javax.xml.transform.*;
            import javax.xml.transform.dom.*;
            import javax.xml.transform.stream.StreamResult;

            import org.w3c.dom.*;

            public class Jaxp_dom {
                public static void main(String[] args) throws Exception {
                    DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();//获得解析器工厂类
                    DocumentBuilder builder=factory.newDocumentBuilder();//获得解析器
                    Document document=builder.parse(new File("books.xml"));//获得指定xml文件的Document对象
                    
                    //add(document,"books.xml");//增
                    //update(document,"books.xml");//改
                    //delete(document,"books.xml");//删
                    query(document);//查
                }
                
                //查
                private static void query(Document document){
                    NodeList list=document.getElementsByTagName("book");//获得指定名称的节点
                    for(int i=0;i<list.getLength();i++){
                        Element element=(Element)list.item(i);//获得每一个节点
                        String value=element.getAttribute("id");//获取指定名称的属性值
                        System.out.println("id-->"+value);
                        
                        NodeList list2=element.getChildNodes();//获取所有子节点(不只是元素节点,换行也算)
                        for(int j=0;j<list2.getLength();j++){
                            Node node=list2.item(j);
                            if(node.getNodeType()==Node.ELEMENT_NODE){//判断是否是元素节点
                                Element element2=(Element)node;
                                String name=element2.getNodeName();//获取节点名称
                                String text=element2.getTextContent();//获取节点文本内容
                                System.out.println(name+":"+text);
                            }
                        }
                    }
                }
                
                //增
                private static void add(Document document,String fileName){
                    Element rootElement=document.getDocumentElement();//获得根元素
                    Element newElement=document.createElement("book");//创建新元素
                    newElement.setAttribute("id", "b003");//设置属性
                    
                    Element newName=document.createElement("title");//添加一个子元素
                    newName.setTextContent("职业生涯规划");//设置元素文本
                    newElement.appendChild(newName);
                    Element newAge=document.createElement("price");//添加一个子元素
                    newAge.setTextContent("22");//设置元素文本
                    newElement.appendChild(newAge);
                    
                    rootElement.appendChild(newElement);//把节点添加到document
                    
                    baoCun(rootElement,fileName);//保存
                }
                
                //改
                private static void update(Document document,String fileName){
                    //先查找再修改
                    NodeList list=document.getElementsByTagName("book");//获得指定名称的节点
                    for(int i=0;i<list.getLength();i++){
                        Element element=(Element)list.item(i);
                        if("b002".equals(element.getAttribute("id"))){
                            NodeList list2=element.getElementsByTagName("title");
                            Element element2=(Element)list2.item(0);
                            element2.setTextContent("数据结构2");//修改
                        }
                    }
                    Element rootElement=document.getDocumentElement();
                    baoCun(rootElement,fileName);//保存
                }
                
                //删
                private static void delete(Document document,String fileName){
                    //先查找再删除
                    NodeList list=document.getElementsByTagName("book");//获得指定名称的节点
                    for(int i=0;i<list.getLength();i++){
                        Element element=(Element)list.item(i);
                        if("b002".equals(element.getAttribute("id"))){
                            element.getParentNode().removeChild(element);//删除
                        }
                    }
                    Element rootElement=document.getDocumentElement();
                    baoCun(rootElement,fileName);//保存
                }
                
                //保存
                private static void baoCun(Element element,String fileName){
                    try {
                        //1 获得转换工厂
                        TransformerFactory transformerFactory = TransformerFactory.newInstance();
                        
                        //2 获得转换器
                        Transformer transformer = transformerFactory.newTransformer();
                        
                        //3.1 将节点封装成转换器需要的源 ,此处使用的是Source接口与dom有关的实现类DOMSource
                        Source xmlSource = new DOMSource(element);
                        //3.2 将保存文件的位置封装转换器需要的结果对象,此处使用的是Result与文件流有关的实现类SteamResult
                        Result outputTarget = new StreamResult(new File(fileName));
                        
                        //4 保存数据,及将指定的节点保存到指定的文件中
                        transformer.transform(xmlSource, outputTarget);
                        
                        System.out.println("保存成功");
                    } catch (Exception e) {
                        throw new RuntimeException(e.getMessage(),e);
                    }
                }
                
                //获取给定元素的所有属性
                private static void getAttrs(Element element){
                    NamedNodeMap maps=element.getAttributes();
                    for(int i=0;i<maps.getLength();i++){
                        Attr attr=(Attr)maps.item(i);
                        String name=attr.getName();
                        String value=attr.getValue();
                        System.out.println(name+"-->"+value);
                    }
                }
            }



jaxp--sax方式解析
    * javax.xml.parsers包
    * DefaultHandler是sax解析事件驱动默认处理类,什么功能都没有完成。需要覆写相应的方法
    * 代码示例
        在项目根目录下创建books.xml
            <?xml version="1.0" encoding="UTF-8"?>
            <books> 
              <book id="b001"> 
                <title>java编程思想</title>  
                <price>68</price> 
              </book>
              <book id="b002">
                <title>数据结构</title>
                <price>32</price> 
              </book> 
            </books>
        创建类
            //1工厂
            SAXParserFactory factory = SAXParserFactory.newInstance();
            //2解析器
            SAXParser saxParser = factory.newSAXParser();
            //3解析
            saxParser.parse(new File("books.xml"), new MyDefaultHandler());
        创建类MyDefaultHandler,继承于DefaultHandler,重写其中的方法即可,例
            package test;
            import org.xml.sax.Attributes;
            import org.xml.sax.SAXException;
            import org.xml.sax.helpers.DefaultHandler;
            public class MyDefaultHandler extends DefaultHandler {
                public void startElement(String uri, String localName, String qName,
                        Attributes attributes) throws SAXException {
                    System.out.println("-->元素开始 : " + qName);
                    //获得属性
                    String id = attributes.getValue("id");
                    System.out.println("id --> " + id);
                }
                public void endElement(String uri, String localName, String qName)
                        throws SAXException {
                    System.out.println("-->元素结束 : " + qName);
                }
                public void characters(char[] ch, int start, int length)
                        throws SAXException {
                    System.out.println("## -->文本 @@ "  + new String(ch,start,length));
                }
            }



dom4j(以dom方式解析xml)
    * 第三方实现对xml进行解析,需导入jar包.(/dom4j/)
    * 核心jar : dom4j-1.6.1.jar
    * 相关jar : xpath表达式 jaxen-1.1-beta-6.jar
    * dom4j是以dom方式解析xml的,dom4j在解析xml时,将生成dom4j的dom树
    * 代码示例:
        注意:代码中使用的xpath表达式,可以去w3cschool学习
        在项目根目录下创建books.xml
            <?xml version="1.0" encoding="UTF-8"?>
            <books> 
              <book id="b001"> 
                <title>java编程思想</title>  
                <price>68</price> 
              </book>
              <book id="b002">
                <title>数据结构</title>
                <price>32</price> 
              </book> 
            </books>
        java代码(需导入两个jar: dom4j-1.6.1.jar和jaxen-1.1-beta-6.jar)
            package test;
            import java.io.File;
            import java.io.FileOutputStream;
            import java.util.List;
            import org.dom4j.*;
            import org.dom4j.io.*;
            public class Test {
                public static void main(String[] args) throws Exception {
                    //获取Document对象
                    SAXReader saxReader=new SAXReader();
                    Document document=saxReader.read(new File("books.xml"));
                    //update(document,"books.xml");//改
                    //add(document,"books.xml");//增
                    //delete(document,"books.xml");//删
                    query(document);//查
                }
                
                //查
                private static void query(Document document){
                    //获取根元素
                    Element rootElement=document.getRootElement();
                    //获得所有元素
                    List allChildElements=rootElement.elements();
                    //循环
                    for(Object o : allChildElements){
                        Element element=(Element)o;
                        String value=element.attributeValue("id");//获取属性值
                        System.out.println(value);
                        List allChildElements2=element.elements();
                        for(Object o2 : allChildElements2){
                            Element element2=(Element)o2;
                            String name=element2.getName();//获取元素名称
                            String text=element2.getTextTrim();//获取元素文本
                            System.out.println(name+":"+text);
                        }
                    }
                }
                
                //改
                private static void update(Document document,String file) throws Exception{
                    //获取根元素
                    Element rootElement=document.getRootElement();
                    //修改
                    Node node=document.selectSingleNode("//book[@id='b001']/title");
                    //使用了xpath表达式,需添加jar包(jaxen-1.1-beta-6.jar)
                    node.setText("java编程思想2");
                    //保存
                    XMLWriter write=new XMLWriter(new FileOutputStream(new File(file)));
                    write.write(document);
                    write.close();
                    System.out.println("修改成功");
                }
                
                //增
                private static void add(Document document,String file) throws Exception{
                    //获取根元素
                    Element rootElement=document.getRootElement();
                    //添加元素
                    Element newElement=rootElement.addElement("book");
                    newElement.addAttribute("id", "b003");
                    newElement.addElement("title").addText("职业生涯规划");//链式编程
                    newElement.addElement("price").addText("30");
                    //保存
                    FileOutputStream out=new FileOutputStream(new File(file));
                    //XMLWriter write=new XMLWriter(out);
                    XMLWriter write=new XMLWriter(out,OutputFormat.createPrettyPrint());//第二个参数可格式化xml的格式
                    write.write(document);
                    write.close();
                    System.out.println("增加成功");
                }
                
                //删
                private static void delete(Document document,String file) throws Exception{
                    //添加元素
                    Node node=document.selectSingleNode("//book[@id='b003']");
                    //使用了xpath表达式,需添加jar包(jaxen-1.1-beta-6.jar)
                    node.getParent().remove(node);
                    //保存
                    FileOutputStream out=new FileOutputStream(new File(file));
                    //XMLWriter write=new XMLWriter(out);
                    XMLWriter write=new XMLWriter(out,OutputFormat.createPrettyPrint());//第二个参数可格式化xml的格式
                    write.write(document);
                    write.close();
                    System.out.println("删除成功");
                }
            }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值