xml

来源:互联网 发布:华住集团 知乎 编辑:程序博客网 时间:2024/06/11 20:58
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、schemaXML 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("删除成功");                }            }
0 0