XML约束

两种xml约束技术:

1.XML DTD

1)DTD是一门XML约束技术,用来约束XML写法。如何在XML中引入一个DTD

  • 外部引入

dtd约束文件存在在一个外部文件中,在XML中引入该约束。可以将dtd的约束内容写在外置的dtd文件中,这个文件后缀必须为.dtd而文件保存时必须用utf-8编码保存,再在xml文件中使用。

  (1)本地文件引入:该dtd文件存在在本地硬盘中。
                    <!DOCTYPE 根元素的名称 SYSTEM "文件所在的路径">
  (2)公共位置文件引入:dtd约束文件存在在一个公共网络上,在XML引入该约束。
                    <!DOCTYPE 根元素的名称 PUBLIC "dtd名称" "dtd所在的URL">

  • 内部引入   

直接在XML内部写dtd约束,在文档声明下:

      <!DOCTYPE 根元素名称 [dtd约束的内容]>

2)dtd语法

(1)元素 <!ELEMENT 元素名称 元素约束>
元素约束:   存放类型:ANY/EMPTY
元素约束:子元素的列表,将可以包含的子元素用小括号括起来。
             子元素之间可以使用
逗号进行分割,表明子元素必须按照顺序出现。
             子元素之间可以使用
竖线进行分割,表面子元素出现其中之一。

#PCDATA 表明包含标签体 
+ 表示一次或多次    
* 0次或多次
? 0次或一次
也可以使用小括号进行组的操作

(2)属性  <!ATTLIST 元素名 
              属性名 属性类型 属性约束
              属性名2 属性类型  属性约束

属性类型:
        CDATA--表示属性的值是一个普通字符串。
        ENUMERATED --属性的值是一个枚举列表中的值。
        ID--表明属性的值必须在整个文档中都是唯一的,如果有重复的id则校验不通过,ID 属性的值只能由字母,下划线开始,不能使用数字,不能出现空白字符。

属性约束:
        #REQUIRED---表明当前属性是一个必须存在的属性,如果这样的属性不存在则在校验时会报错。
        #IMPLIED---表明当前属性是一个可选的属性,可以有也可以没有
        #FIXED '固定值'---表明当前属性具有一个固定值,这样的属性不需要进行赋值,自动就会取这个固定值为值。如果这样的属性指定了一个不是固定值的值则校验报错。
        '默认值'---表明当前属性具有一个默认值,如果给了其他的值就用其他值,如果没有给值则取这个默认值。

(3)ENTITY(实体)
        <!ENTITY  >,就是对一大段内容的引用,可以简化代码的复用。

  • 引用实体:在xml中引用的实体叫做引用实体

            <!ENTITY 实体名称 “实体内容” >
            &实体名称;--使用

  • 参数实体:在dtd中引用的实体叫做参数实体。

            <!ENTITY % 实体名称 "实体内容">
            %实体名称;

2.XML Schema

XML编程:利用java程序去增删改查(CRUD——create/read/update/delete)xml中的数据。

xml的两种解析方式:

  • dom解析(document)

读文档时,先创建一个Document:dom对象代表整个文档,Element:root根节点,在创建子标签,子标签下面有子子标签,子子标签下面有标签体。都实现了Node接口,提供了增删改查节点的方法。

优点:十分便于进行增删改查的操作;只需要解析一次拿到dom对象后可以重复使用此对象减少解析次数。

缺点:解析过程比较慢,需要将整个文档都解析完成后才能进行操作;需要将整个树中的内容加载到内存中,比较耗费内存,当文档过大时,这种解析方式对内存损耗非常严重。

解析包:

sun公司 jaxp既有dom方式也有sax方式,并且这套解析api已经加入到j2se的规范中,意味这不需要导入任何第三方开发包就可以直接使用这种解析方式,但是这种解析方式效率低下,没什么人用。


dom4j 可以使用dom方式高效的解析xml。(以下代码以dom4j解析包为基础,导入开发包,通常只需要导入核心包就可以了,如果在使用的过程中提示少什么包到lib目录下在导入缺少的包即可。)

//1.获取解析器
SAXReader reader = new SAXReader();
//2.解析xml获取代表整个文档的dom对象
Document dom = reader.read("book.xml");
//3.获取根节点
Element root = dom.getRootElement();
//4.获取书名进行打印.root为书架-书-书名
String bookName = root.element("书").element("书名").getText();
System.out.println(bookName);
  • 创建新的标签(增)
//1.获取解析器 
SAXReader reader = new SAXReader(); 
//2.解析xml获取代表整个文档的dom对象 
Document dom = reader.read("book.xml");
//3.创建<特价>标签,设置标签体
Element price2Ele = DocumentHelper.createElement(“特价”);
//4.设置标签体,值
price2Ele.setText("20元");
//5.获取父标签<书>将特价节点挂载上去
Element bookEle = root.element("书");
bookEle.add(price2Ele);
//6.将内存中的dom树回写到xml文件中,从而使xml文件内容更新
FileWriter f = new FileWrite("book.xml"); 
dom.write(f);
f.flush();
f.close();
  • 增 --  第二种:(dom写入xml文档的方法)
XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),
OutputFormat.createPrettyPrint());//加红色更好看

writer.write(dom); 
writer.close();
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
root.element("书").element("特价").setText("10.0元");
XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint());
writer.write(dom);
writer.close();
//删除的思想是在父类里面删除
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
//先取到特价
Element price2Ele = root.element("书").element("特价");
//找到父标签,删除子标签
price2Ele.getParent().remove(price2Ele);
XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint());
writer.write(dom);
writer.close();
  • 增加属性或者修改(没有当前属性就增加,有的话就修改)
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
		
Element bookEle = root.element("书");
bookEle.addAttribute("出版社", "传智出版社");

XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint());
writer.write(dom);
writer.close();
  • 读取属性 

 

SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
		
Element bookEle = root.element("书");
String str = bookEle.attributeValue("出版社");
System.out.println(str);
  • 删除属性
//拿到属性对对象,从父标签删除属性。
Attribute attr = bookEle.attribute("出版社");
attr.getParent().remove(attr);
  • sax解析(用的多)

解析器:(eclipse提供)

事件处理器:(由开发人员编写)事件处理机制

                        文档解析开始(){......}

                        发现元素的开始标签(){......}

                        发现元素的结束标签(){......}

                        文档解析结束(){......}

优点:不需要等待整个xml加载到内存,当解析到某一部分时,自动触发到对应的方法去处理,处理的效率比较高;不需要将整个文档加载到内存中,对内存的损耗比较少,无论多大的xml理论上都可以解析。

缺点:每次解析都只能处理一次,下次再想处理只能重新解析;正能进行查询,不能进行增删改处理。

## sax解析
    //获取解析器工厂
    SAXParserFactory factory = SAXParserFactory.newInstance ();
    //通过工厂获取sax解析器
    SAXParser parser = factory.newSAXParser ();
    //获取读取器
    XMLReader reader = parser.getXMLReader ();
    //注册事件处理器
    reader.setContentHandler (new MyContentHandler ());
    //解析xml
    reader.parse ("book.xml");

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值