JavaWeb基础—XML学习小结

一、概述

  是什么? 指可扩展标记语言
  能干什么? 传输和存储数据
  怎么干? 需要自行定义标签。

  XML 独立于硬件、软件以及应用程序

  通常。建立完xml文件后首要的任务是:引入约束文件!

二、XML简介:可扩展标记语言,都是标记语言,通过标签来操作
  具有拓展性,标签为预定义,用户自定义标签(包括自己定义中文标签)
  HTML:显示数据。
  XML: 存储数据。(小型数据库)
  两个版本:1.0(主流) 1.1(兼容性差)
  用途:1.不同系统之间数据的传输(qq发送数据为例)
     2.表示生活中有关系的数据
     3.经常用在配置文件

三、XML的语法:

  1.文档声明

     <?xml version="1.0" encoding="gbk"?>
    注意格式与位置(必须第一行第一列)
    xmlns表示xml namespace
    中文乱码问题的解决:一般系统默认的编码方式为gbk,打开时使用另外的编码方式
    故出现乱码现象。解决方式是设置保存时候编码与打开方式编码相同:另存为时设置
    编码方式。
  2.元素的定义 
    A.有开始必须要有结束,必须成对出现。<person></person>
    【成对】在 XML 中,省略关闭标签是非法的。所有元素都必须有关闭标签
    标签没有内容,可以在标签内结束。<mytag/>
    可以合理嵌套
    只有一个根标签,其它都是子标签或是孙标签等。
    B.空格和换行都会当成原始内容处理
    <person>
    人 <person>人</person> 两种是不同的
    </person>
    C。命名规范:区分大小写(HTML不区分)
    不能以数字和_开头
    不能以xml XML等开头
    不能包含空格
    不能包含冒号:
    D.属性:一个标签可以有多个属性,但不能有相同的属性
    E.注释:同HTML <!-- -->,注释不允许嵌套。快捷键Ctrl shift /
    3.特殊字符
    如 < &lt; > &gt; " &quot; ' &apos & &amp类同HTML
    4.CDATA区:解决多个字符都需要转义的操作
    写法:<![CDATA[内容]]>
    5.PI指令(处理指令)
    对XML样式的设置,引入CSS样式等。但只能设置英文标签的样式
    6.XML约束:
  dtd约束(以看懂为准)
    创建.dtd文件约束,看xml中有几个元素,就在dtd中写几个<!ELEMENT>
    再判断是简单元素或者复杂元素(有无子元素等);复杂元素则表示为<!ELEMENT 元素名称(子元素)>
    如<!ELEMENT person(name,age)>:简单元素则表示为<!ELEMENT 元素名称(#PCDATA)>
    再引入dtd文件:<!DOCTYPE 根元素名称 SYSTEM "dtd文件路径">

            另一书根元素名称通常记录为dtd文件名称

    dtd三种引入方法:1.见上。文件引入
             2.使用内部dtd <!DOCTYPE 根元素名称 []>
        <!DOCTYPE note [
        <!ELEMENT note (to,from,heading,body)>
        <!ELEMENT to (#PCDATA)>
        <!ELEMENT from (#PCDATA)>
        <!ELEMENT heading (#PCDATA)>
        <!ELEMENT body (#PCDATA)>
        ]>
          3.使用外部dtd (网络上的dtd)
      <!DOCTYPE 根元素名称 PUBLIC "DTD名称" "DTD文档的URL"> (struts2框架应用)

        下载一个dtd文件后,复制第一行到xml文件即为成功引入,这里给出第一个接触用法的例子

          <!DOCTYPE hibernate-mapping PUBLIC
          "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">


      使用dtd定义元素:<!ELEMENT 元素 约束>
      简单元素约束举例:<!ELEMENT name (#PCDATA)> 约束为字符串
      EMPTY 约束元素为空
      ANY 任意
      复杂元素约束举例:<!ELEMENT person (name,age)>
      name+:表示可以出现一次或者多次
      name?:表示出现0次或者1次
      name*:表示任意次数
      ,表示出现的顺序,
      name|age表示只能出现其中一个,或的关系
      使用dtd定义属性:<!ATTLIST 元素名称
      属性名称 属性类型 属性约束
      >
      属性类型一共三种 属性约束分类
      CDATA 字符串 #REQUIRED 必须出现的
      ENUM 枚举类型(aa|bb) #IMPLIED 可有可无
      ID类型 字母或者_开头 #FIXED "AA" 固定值,如AA
      直接值(没写则按照这个值)
      定义实体 <!ENTITY copyright "版权所有"> 引用 &copyright 一般写在内部dtd中
      W3C案例

  schema约束
    schema符合XML语法,不能像dtd一样语法自成一派。
    可以有多个schema,而dtd只能有一个。使用名称空间进行区分(类似包名进行区分)
    可以支持更多的数据类型(不止字符串#PCDATA类型)
    更复杂,约束更强大。

    创建一个schema文件 .xsd
    先看有多少个元素,就有多少个<element> 根元素 <schema></schema>
    w3c预定义了属性和标签 xmlns=""表明是一个约束文件 targetNamespace="url"可以通过这个地址进行引入
    看是简单或者复杂元素。
    复杂元素:<complexType>
    <sequence>
    子元素(就是下面的简单元素内容
    </sequence>
    </complexType>

    除了sequence 还可以有其它的:
    <all></all> 表示元素只能出现一次
    <choice></choice> 只能出现一个
    maxOccurs="unbounded" 元素出现次数无限制
    <any></any> 任意
    简单元素:<element name="name" type="string"></element>
    <element name="age" type="int"></element>

    在XML中引入schema文件,在xml根元素上面,<person xmlns="在schema的xmlns后加-instance"
    定义属性(必须是复杂元素)写在</complexType>之前
    <attribute name="id1" type="int" use="required"></attribute>


四、XML解析方式【重点】
js中的DOM解析方式为根据层级结构分配树形结构,标签、属性、文本都封装成对象

XML解析方式:DOM和SAX
  DOM:类同上述;树形结构容易完成增删改操作,但同时文件过大容易造成内存溢出
  SAX:采用事件驱动,边读边解析。解析到一个对象则返回该对象名称。
  容易查询,但不易于增删改操作
XML的解析器:不同公司提供了针对的解析器,以API文档形式给出。
   jaxp【sun公司提供】
  dom4j【实际开发使用最多】(XPath)
  jdom

  jaxp的API,属于SE部分,能在JDK中查到,javax.xml. parsers(解析)包
  主要包含以下类(操作会出现格式混乱的问题:
    dom:DocumentBuilder 解析器的类,抽象类(不能new)
    DocumentBuilderFactory.newDocumentBuilder()方法获得
    parse(string url)解析出整个文档document接口(父接口为Node)子接口中找不到方法时找父接口
    DocumentBuilderFactory 解析器的工厂
    newInstance();获取

    查询操作:
    得到工厂-》得到解析器-》得到Document-》document.getElementsByTagName()得到Nodelist,遍历等。
    getTextContent()得到具体值

    添加操作:
    得到Document及之前操作同上,创建需要添加的元素,类同js。得到父元素(拿到第一个.item(0))
    再进行操作,但此时操作的是内存里面的文档,最后要加一步回写。
    通过TransformerFactory 和Transformer(得到方法同上)
    再通过.transform(new DOMSource(document),new StreamResult("url"));方法回写

    修改使用setTextContent()方法;其它类同上。
    注意getElementsByTayName得到的是集合,要访问带.item(0)方法

    同样的删除操作使用父节点进行删除。

    采用递归进行遍历:访问自己。访问子节点。递归调用。
    判断元素类型再进行打印。

    sax:SAXParser 解析器类
    SAXParserFactory 解析器的工厂

    得到SAXParser实例类同上,使用的方法:parse(File,DefauleHander);
    参数一为xml的路径,参数二为事件处理器(自动执行这个事件)
    三个主要方法:startElement() :遇到开始标签自动执行此方法<start>
    endElement() :遇到结束时自动执行</start>
    characters():遇到文本时执行此方法 开始文本
    qName:把标签名返回

    使用dom4j解析XML,提供了解析器dom4j,由于dom4j是另外的组织开发的,不属于se的一部分。

      默认情况下dom4j是不支持XPATH的,第一步需要引入jar包:dom4j下lib/jaxen
    dom4j下提供两个方法支持XPATH,在document里调用
    selectNodes("xpath表达式");返回Node,强转成element
    selectSingleNode("xpath表达式");
    所以第一步当然是导包。创建一个folder,复制jar包,点击jar包右键build path>add to path>变成奶瓶的样子
    一般找docs就先看index.html,
    得到document的方法:
    SAXReader reader = new SAXReader();
    Document document = reader.read(url);
    document里面的方法:getRootElement();返回Element,也是接口(Node子接口)
    Element里面的方法:getParent():得到父节点 addElement():添加标签
    使用dom4j进行查询操作【XPath更方便】(增删改查操作)getText setText
    创建解析器SAXReader,read()方法得到document,
    得到根节点,getRootElement()
    得到一层层的标签直到需要的标签(从上到下解析)
    注意返回值,Element 与List<Element>
    element(qname)得到标签下面第一个name子标签
    elements()获取标签下面的一层子标签
    elements(qname)所有一层子标签
    使用dom4j进行元素末尾的添加操作(注意回写操作)
    得到根节点之前同上。
    得到P1,直接添加元素(不需要像前面一样先创建)
    Element sex1 = p1.addElement("sex"); sex1.setText("nv");
    使用这个类进行回写XMLWriter xmlWriter = new XMLWriter(OutputStream out, OutputFormat format)
    一个是输出流 new FileOutputStream(xml路径),一个是格式
    OutputFormat format = OutputFormat.createPrettyPrint();(是静态方法,直接类名调用,漂亮的格式,即有缩进的)
    最后加一个回写回去,xmlWriter.write(document);
    当然,流打开那必须关闭,xmlWriter.close();

    在特定位置添加元素,应该在上一级用Elements返回list,
    在list中使用list.add(index,element);需要创建一个用于添加
    使用documentHelper帮助类,使用createElement()静态方法 documentHelper.createElement();

    将部分代码封装到一个Utils类,封装成相关方法,常量如路径,
    表示成public static final String PATH = "";
    使用dom4j进行修改操作(重复部分使用封装的方法(得到Document)与回写与常量(路径等)等)
    得到需要的标签后,setText()即可。
    使用dom4j进行删除节点的操作,同样需要使用父节点进行删除,(可以使用getParent()方法获取父节点)
    方法与Js稍有区别,remove()进行删除

    【!】attributeValue()方法,得到属性值

    使用dom4j支持XPath的操作,可以直接获取到某一个元素,而不用一层一层解析,
    这里的XPath就类似于一种写法,一种表达式。详见手册前六实例。
    /AAA/DDD/BBB一个/表示一层一层
    //BBB每一层的BBB,不管哪一层都可以,只要名字相同
    /AAA/BBB/*表示BBB下所有的
    /AAA/BBB[1] 第一个BBB /AAA/BBB[last()] 最后一个BBB
    //BBB[@id] 选择有id属性的所有BBB元素
    //BBB[@id='b1'] 选择id属性为指定值的所有BBB

    

原文地址:https://www.cnblogs.com/jiangbei/p/6679900.html