zoukankan      html  css  js  c++  java
  • xml基本写法和dtd schema的用法,JAVA读写XML

    1. 标记语言


       标记语言,是一种文本(Text)以及文本相关的其他信息结合起来,展现出关于文档结构和数据处理细节的电脑文字编码.当今广泛使用的标记语言是超文本标记语言(Hyper Text Markup Language,HTML)和可扩展标记语言(eXtensible Markup Language,XML). 标记语言广泛应用于网页和网络应用程序.


     1) 超文本标记语言HTML(Hyper Text Markup Language)


      写法格式: <a href="link.html">link</a>
      关注数据的展示与用户体验
      标记是固定的,不可扩展(如<a></a>表示超连接)


     2) 可扩展的标记语言XML(eXtensible Markup Language)


      写法格式:同html样式<a>link</a>
      仅关注数据本身
      标记可扩展,可自定义


     3) Xml 和 Html语言由同一种父语言SGML(Standard Generalized Markup language,标准通用标记语言)发展出来.


     4)解析器


      专业解析器(比如:XML SPY 专用于解析XML文件)
      浏览器
      MyEclipse


     5)W3C(World Wide Web Consortium)


      W3C:开源的语言协会,万维网联盟(World Wide Web Consortium)
      HTML 和 XML 都是W3C制定的语言规则
      官网:www.w3.org
      学习网站:www.w3school.com.cn

    2.xml语法规则


    2.1 xml的声明:


    xml的声明必须写在文件第一行
    Encoding(字符集)属性可以省略,默认的字符集是utf-8
    例子:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <>
     3  <武侠小说 isbn="1001">
     4   <书名>天龙八部</书名>
     5   <作者>金庸</作者>
     6   <价格>50</价格>
     7   <简介>一本好书</简介>
     8  </武侠小说>
     9  <计算机>
    10   <书名>疯狂java</书名>
    11   <作者>李刚</作者>
    12   <价格>50</价格>
    13   <简介>一本好书</简介>
    14  </计算机>
    15 </>

    常见错误写法:
    1) "?"和xml之间不能有空格
    2) 声明必须顶头写,不能有空行或空格(用FireFox浏览器打开)
    3) 等号左右不要多写空格(java程序员的习惯)
    浏览器不会报错,但是在xml解析时会出问题

    2.2 标记


    1)诸如<书名></书名>,这样格式的被称为标记
    2)标记必须成对出现
    3)标记包含开始标记和结束标记

    <书名>天龙八部</ 书名>

    注意:标记大小写敏感

    2.3元素(Element)

    1) 元素: 元素= 标记 + 其中内容  ,

    如<书名>天龙八部</书名>


    2) 根元素: 最外层的元素 (如  <书></书>)


    3) 叶子元素: 最里层(没有子元素的)的元素  (如,<书名></书名>,<价格></价格>)


    4) 空元素: 没有内容的元素叫空元素,比如:<a></a> ,<br></br>,可以简写为<a/> <br/>


    5) 元素必须遵循的语法规则


     a. 所有的标记都必须有结束
     b.开始标记和结束标记必须成对出现
     c.元素必须正确嵌套
     <a><b>c</b></a> (正确)
     <a><b>c</a></b> (错误)
     d.标记的大小写敏感Hello 和 hello不是同一个标记
     e.有且只能有一个根元素

    2.4 实体引用(转义字符)


    1) 小于号(<) : less then --> &lt;


    2) 大于号(>) : great than --> &gt;


    3) And符号(&) :  &amp;


    4) 双引号 ( ") : &quot;


    5) 单引号( ') : &apos;


    注意这些转义字符都是以&开头,以 ; 结尾

    例如:想给天龙八部加上书名号<<天龙八部>>

    <?xml version="1.0" encoding="UTF-8"?>
    <>
     <武侠小说 isbn="1001">
      <书名>&lt;&lt;天龙八部&gt;&gt;</书名>
      <作者>金庸</作者>
      <价格>50</价格>
      <简介>一本好书</简介>
     </武侠小说>
    </>

    2.5属性(定义在开始标记中的键值对)


    1)格式: 属性="属性值"
    如<武侠小说 isbn="1234"></武侠小说>
    isbn是武侠小说的属性,值是1234
    2)要求:
     属性必须有值
     属性值必须用引号引起来,单引号或双引号都可以,但必须一致


    2.6 CDATA 类型的数据:特殊标签


    1) 格式: <![CDATA[文本内容]]>
    2) 特殊标签中的实体引用都被忽略,所有内容被当成一整块文本数据对待
    例如

    <>
     <武侠小说 isbn="1235" lang="zh">
      <书名 hot="true">笑笑江湖</书名>
      <作者>金庸</作者>
      <价格>45</价格>
      <简介>
      <![CDATA[
      一本好书,没有<<笑傲江湖>>好看
      ]]>
      </简介>
     </武侠小说>
    </>

    2.8 注释(xml和html相同)


    1)格式:  <!-- 这是一段注释 -->
    2) 编译器将忽略注释
    3) Html和xml注释方式相同
    例子:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <>
     3  <!-- 这是一段注释 -->
     4  <武侠小说 isbn="1001">
     5   <书名>&lt;&lt;天龙八部&gt;&gt;</书名>
     6   <作者>金庸</作者>
     7   <价格>50</价格>
     8   <简介>一本好书</简介>
     9  </武侠小说>
    10 </>

    2.8 规则小结


    1) 必须有唯一的根元素
    2) xml标记大小写敏感
    3) 标记必须配对出现,有开始有结束
    4) 元素必须被正确嵌套
    5) 属性必须有值,值必须用引号引起来
    6) 如果遵循全部上述规则,称作well-formed文件(格式良好的xml文件)

    2.9 使用XML文件描述数据的例子
    1) 早期属性文件描述数据的方式
     url = jdbd:oracle:thin@192.168.0.205:1521:dbsid
     dbUser = openlab
     dbPwd = open123
    2) 现在使用xml表示方式
     

    <?xml version="1.0" encoding="UTF-8"?>
    <>
     <!-- 这是一段注释 -->
     <武侠小说 isbn="1001">
      <书名>&lt;&lt;天龙八部&gt;&gt;</书名>
      <作者>金庸</作者>
      <价格>50</价格>
      <简介>一本好书</简介>
     </武侠小说>
    </>

    3. DTD/Schema


    1) DTD/Schema:用来规范XML的标记规则


    2) 有效的xml文件(valid xml file) = 格式良好的xml文件 + 有DTD或Schema规则 + 遵循DTD或Schema规则


    3.1 DTD/Schema的作用
     行业交换数据时要求xml文件格式相同,所以需要大家遵守规范的xml文件格式,比如两份xml文件要有相同的元素嵌套关系,相同的属性定义,相同的元素顺序,元素出现相同次数等

    3.2文档类型定义DTD(Document Type Difinition)


    1) DTD文档用来定义XML文件的格式,约束XML文件中的标记规则
    2) DTD类型
     PUBLIC(行业共用的)
     SYSTEM(小范围自定义的)

    3.2.1 DTD中的定义规则


    必须列出所有节点,一个都不能少


    1)元素
    "*"星号  表示可以出现0-n次
    "+"加号  表示可以出现1-n次
    "|"   表示或(只能出现一个)
       如(phone|mobile)表示固话或手机二选一
    "?"问号:  表示出现0或1此
    #PCDATA 表示字符串


    2)属性:
    定义在开始标记中的键值对
    dtd 规则_属性
    1) <!ATTLIST 标记名称 属性名称 属性类型>
    2) isbn CDATA #REQUIRED: 表示isbn属性是必须的
    3) isbn CDATA #IMPLIED: 表示isbn属性不是必须的
    4) hot CDATA"false" :表示hot默认值是false
    例子3.2.1
    首先是dtd文件book.dtd
     

    <!ELEMENT 书 (武侠小说, br)*>
     <!ELEMENT 武侠小说 (书名,作者+,价格,简介)>
     <!ELEMENT 书名 (#PCDATA)>
     <!ELEMENT 作者 (#PCDATA)>
     <!ELEMENT 价格 (#PCDATA)>
     <!ELEMENT 简介 (#PCDATA)>
     <!ELEMENT br EMPTY>
     <!ATTLIST 武侠小说 isbn CDATA #REQUIRED   
        lang CDATA #IMPLIED>
     <!ATTLIST 书名 hot CDATA #IMPLIED>

    在XML中使用

    <?xml version="1.0"?>
    <!DOCTYPE 书  SYSTEM "book.dtd">
    
    <>
     <武侠小说 isbn="1234" lang="zh">
      <书名 hot="false">&lt;&lt;天龙八部&gt;&gt;</书名>
      <作者>金庸</作者>
      <作者>古龙</作者>
      <价格>45</价格>
      <简介>一本好书</简介>
     </武侠小说>
    <br></br>
     <武侠小说 isbn="1235" lang="zh">
      <书名 hot="true">笑笑江湖</书名>
      <作者>金庸</作者>
      <价格>45</价格>
      <简介>
      <!-- 这是一段注释 -->
      <![CDATA[
      一本好书,没有<<笑傲江湖>>好看
      CDATA中的所有特殊字符都不解释(原样显示)
      ]]>
      </简介>
     </武侠小说>
     <br></br>
    </>

    3.3 Schema ,DTD的升级版


    与DTD的区别
    1)命名空间(NameSpace) 
    XML文件允许自定义标记,所以可能出现来自不同源DTD或Schema文件的同名标记,为了区分这些标记,就需要使用命名空间.
     命名空间的目的是有效的区分来自不同DTD的相同标记
     比如xml中文件中使用了命名空间区分开"表格"和"桌则":
     <html:table>
      <line><column>这是一个表格</column></line>
     </html;table>
     <product:table>
      <type>coff table</type>
     <product:table>
    2) 因为DTD无法解决命名冲突,所以出现Schema,它是DTD 的替代者,dtd和Schema的功能都是描述xml结构的


    3) Schema使用xml语法实现(Schema本身就是xml文件)
    因为用于规范和描述xml文件的定义文件(schema)本身也是xml文件,所也xml也被称为自描述的语言


    4) Schema 文件的扩展名xds: XML Schema Difinition(简称XSD,遵循W3C标准)
    5) Schema中的名词:
     复杂元素(有子元素的元素)
     简单元素(叶子元素)


    例子:email.xsd

    <?xml version="1.0" encoding="UTF-8"?>
    <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/email" xmlns:tns="http://www.example.org/email" elementFormDefault="qualified">
     <element name="email">
      <complexType>
       <sequence>
        <element name="from" type="string"/>
        <element name="to" type="string"/>
        <element name="subject" type="string"/>
        <element name="body" type="string" />  
       </sequence>
      </complexType>
     </element>
    </schema>

    被规范的文件email.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <tns:email xmlns:tns="http://www.example.org/email" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/email email.xsd ">
      <tns:from>赵敏</tns:from>
      <tns:to>张无忌</tns:to>
      <tns:subject>HIHI</tns:subject>
      <tns:body>看泰坦尼克号</tns:body>
    </tns:email>

    3.4 根据DTD或者Schema来写xml文件的方法
    在MyEclipse中右键New --> xml (Basic Templates) -->输入文件名-->next-->选择是DTD还是Schema


    4. java API 解析XML文件(读xml文件)
    1) Java 与xml有很多共同点(比如跨平台,与厂商无关),目前位置java对xml的解析较其他语言更完善


    2) 两种解析方式:
     DOM(Document Object Model 文档对象模型)
     关键字:树(Document)
     优点: 把xml文件在内存中构造树形结构,可以遍历和修改节点
     缺点: 如果文件比较大,内存有压力,解析的时间会比较长
     
     SAX(Simple API for Xml基于XML的简单API)
     关键字:流(Stream)
     把xml文件作为输入流,触发标记开始,内容开始,标记结束等动作
     优点:解析可以立即开始,速度快,没有内存压力
     缺点:不能对节点做修改
    3) JDOM/DOM4J : 目前市场上常用的两种解析XML文件的API
     dom4j-1.6.1.jar 结合了DOM和SAX两种解析方式的优点


    DOM4j解析xml文件步骤
    1) 创建项目XMLDemo
    2) 加入dom4j的jar包(dom4j-1.6-1.jar)
    3) 将要解析的xml文件放在路径src/下
    4) 新建ReadXMLDemo.java
    4-1)构造document对象
    SAXReader reader = new SAXReader();
    Document doc = reader.read(file);
    4-2)取根元素:
    Element root = doc.getRootElement();
    4-3)常用方法
    Element elmt;
    elmt.elements("标记名称"):取出所有指定标记名称的元素
    elmt.element("标记名称"):取出第一个指定标记名称元素
    elmt.elementText("标记名称"):取elmt指定名字的子元素
    elmt.getText();取当前元素的内容

    Iterator it = elmt.elementsIterator("标记名称") 返回一个Iterator
    String 属性值 = elmt.attattributeValue("属性名")

    例子:ReadBookdemo源代码

    package day1;
    import java.io.*;
    import java.util.*;
    import org.dom4j.*;
    import org.dom4j.io.*;
    /**
     * 读入book.xml文件,取出数据并打印
     * @author soft01
     *
     */
    public class ReadBookdemo {
     public static void main(String[] args) {
       readBook("book.xml");
     }
    /**
     * 读入指定的xml文件,取出数据并打印
     * @param string
     */
     private static void readBook(String filename) {
      //1..读入指定的文件,构造Document对象
      File file = new File(filename);
      SAXReader reader = new SAXReader();//XML文件解析器
      try {
       Document doc = reader.read(file);//解析器开始解析xml文件
       //2.获得根元素
       Element root = doc.getRootElement();
       //3.递归搜索子元素
      /* List<Element> list = root.elements("武侠小说");
       //迭代武侠小说的元素集合
       Iterator<Element> it = list.iterator(); */
       Iterator<Element> it = root.elementIterator("武侠小说");
       while(it.hasNext()){
        Element bookElmt = it.next(); //bookEmlt是武侠小说元素
        //取武侠小说的子元素
        System.out.println(bookElmt.elementText("书名"));//取 子元素  书名 的内容
        List<Element> authorList = bookElmt.elements("作者");
        for (Element element : authorList) {
         //打印 作者 元素内容
         System.out.println(element.getText());
        }
        System.out.println(bookElmt.elementText("价格"));
        System.out.println(bookElmt.elementText("简介"));
        
        //取 武侠小说 的 属性
        String isbnValue = bookElmt.attributeValue("isbn");
        //取 武侠小说 的 lang元素
        String langValue = bookElmt.attributeValue("lang");
        System.out.println("isbn="+isbnValue);
        System.out.println("lang="+langValue);
        
        //取子元素中的属性
        Element nameElmt = bookElmt.element("书名");
        System.out.println(nameElmt.attributeValue("hot"));
        System.out.println("-----------------");
       }
       } catch (DocumentException e) {
       e.printStackTrace();
      }
     } 
    }

    book.xml如下

    <?xml version="1.0"?>
    <>
     <武侠小说 isbn="1234" lang="zh">
      <书名 hot="false">&lt;&lt;天龙八部&gt;&gt;</书名>
      <作者>金庸</作者>
      <作者>古龙</作者>
      <价格>45</价格>
      <简介>一本好书</简介>
     </武侠小说>
     <br></br>
     <武侠小说 isbn="1235" lang="zh">
      <书名 hot="true">笑笑江湖</书名>
      <作者>金庸</作者>
      <价格>45</价格>
      <简介>
      <!-- 这是一段注释 -->
      <![CDATA[
      一本好书,没有<<笑傲江湖>>好看
      CDATA中的所有特殊字符都不解释(原样显示)
      ]]>
      </简介>
     </武侠小说>
     <br></br>
    </>

    5 DOM4j API解析XML文件(生成)


    1)常用API方法:
     给元素增加子元素: elmt.addElement("标记名称");
     给元素增加属性:  elmt.addAttribute("属性名","属性值");
     给叶子元素设值: elmt.setText("元素值");
    例如:
    要生成以下xml文件

    <book isbn="1001" catalog = "科幻">
     <name>阿里波特</name>
     <author>罗林</author>
     <price>60</price>
     <year>2005</year>
    </book>

    步骤:
    1.构造空的Document
    2.构造根元素
    3.递归构造子元素
    4.输出

    WriteBookDemo源代码

    package day1;
    import java.io.*;
    
    import org.dom4j.*;
    import org.dom4j.io.*;
    /**
     * 利用DOM4J写出xml文件
     * @author soft01
     *
     */
    public class WriteBookDemo {
     static String [][] data={
       {"1001", "科幻", "阿里波特", "罗林","60", "2005","en"},
       {"1002", "迷幻", "小波特", "罗4林","60", "2005","zh"},
       {"1003", "玄幻", "中波特", "罗3林","60", "2005","en"},
       {"1004", "奇幻", "大波特", "罗2林","60", "2005","zh"}
     };
     public static void main(String[] args) {
      writeBook("mybook.xml");
     }
     /**
      * 把书的数据生成到指定名字的xml文件中
      * @param filename
      */
     public static void writeBook(String filename){
    //  1.构造空的Document
      Document doc = DocumentHelper.createDocument();
    //  2.构造根元素
      Element rootElmt = doc.addElement("booklist");
    //  3.递归构造子元素
      for(String[] book:data){
       Element bookElmt = rootElmt.addElement("book");
       //book 元素增加属性
       bookElmt.addAttribute("isbn", book[0]);
       bookElmt.addAttribute("catalog", book[1]);
       
       Element nameElmt = bookElmt.addElement("name");
       nameElmt.setText(book[2]);
       //给name 加属性
       nameElmt.addAttribute("lang", book[6]);
       Element authorElmt = bookElmt.addElement("author");
       authorElmt.setText(book[3]);
       Element priceElmt = bookElmt.addElement("price");
       priceElmt.setText(book[4]);
       Element yearElmt = bookElmt.addElement("year");
       yearElmt.setText(book[5]);
      }
    //  4.输出
      outputXml(doc,filename);
      
     }
     public static void outputXml(Document doc,String filename){
      try {
       //定义输出流的目的地
       FileWriter fw = new FileWriter(filename);
       //定义输出格式 和 字符集
       OutputFormat format = OutputFormat.createPrettyPrint();
       format.setEncoding("UTF-8");
       //定义用于输出xml文件的XMLWriter对象
       XMLWriter xmlWriter = new XMLWriter(fw,format);
       xmlWriter.write(doc);
       xmlWriter.close();
       
      } catch (IOException e) {
       e.printStackTrace();
      }
     }
    }

    注意:运行程序生成的mybooks.xmlpackage day1;
    不自动装载,需要刷新一下
    程序运行通过后,在项目上点击右键"refreash"(或F5)
    如果是从别的工作区导入的项目,需要去别的工作区目录下找生成的XML文件

    6XPath(w3c的标准)
    1) XPath:在XML文件中查找或定位信息的语言,相当于SQL中的 select
      XPath 可以通过元素/属性/值来定位或导航
    2) 节点(Node):相当于xml文件中的元素
    3) 指定条件定位元素的方式

    例子:

    package day1;
    import java.io.*;
    import java.util.*;
    
    import org.dom4j.*;
    import org.dom4j.io.*;
    /**
     * 测试XPath的功能
     * @author soft01
     *
     */
    public class XPathDemo {
     public static void main(String[] args) {
      findBook("mybook.xml");
     }
     public static void findBook(String filename){
      SAXReader reader = new SAXReader();
      try {
       //获得文档对象
       Document doc = reader.read(new File(filename));
       Node node = 
        doc.selectSingleNode("/booklist");
       
       //查找所有的catalog="奇幻"的书2
       //String sql = "book[@catalog ='奇幻']";
       //价格>50的书
       //String sql = "book[price>50]";
       //作者等于罗林的书,并且价格大于50
       //String sql ="book[author='罗林' and price>50]";
       //价格大于50,且语言是zh
       String sql = "book[price>50 and name[@lang='zh']]";
       List<Element> books = node.selectNodes(sql);
       for(Element e:books){
        System.out.println(e.getStringValue());
       }
      } catch (DocumentException e) {
       e.printStackTrace();
      }
     }
    }
    
     
  • 相关阅读:
    第十一次作业——LL(1)文法
    wechall前十题
    [V&N2020 公开赛]TimeTravel 复现
    CTFHub web技能树之RCE初步 命令注入+过滤cat
    算法第四章作业
    算法第四章上机实践报告
    算法第三章作业
    算法第三章上机实践报告
    算法--第二章作业
    算法第二章上机报告
  • 原文地址:https://www.cnblogs.com/hqr9313/p/2502662.html
Copyright © 2011-2022 走看看