JavaWeb学习__第1天_xml&dom_sax_dom4j编程

1.XML概述

    XML是指可扩展标记语言(eXtensible Markup Language),它是一种标记语言,很类似HTML。它被设计的宗旨是传输数据,而非显示数据。
    XML标签没有被预定义,需要用户自行定义标签。
    XML处理生活中具有相关联系的数据,描述具有关系的数据,是一种通用的数据交换格式
    用于解析执行或者显示的程序称为Parser(解析器)
  

    常见应用:
    XML技术除用于保存有关系的数据之外,它还经常用作软件配置文件,以描述程序模块之间的关系。
    在一个软件系统中,通过XML配置文件可以提高系统的灵活性。即程序的行为是通过XML文件来配置的,而不是硬编码。

2.XML语法

    文档声明 
    <?xml version=”1.0” ?>
        声明文档必须写在第一行第一列
    用encoding属性说明文档所使用的字符编码。保存在磁盘上的文件编码要与声明的编码一致。
        <?xml version=“1.0” encoding=”GB2312”?>
    用standalone属性说明文档是否独立,即是否依赖其他文档。
        <?xml version=“1.0” standalone=”yes”?>
  元素
      也可以叫做标签,一个正确的标签包括开始标签和结束标签。
      包含标签主体:<mytag>some content</mytag>
        不含标签主体:<mytag/>
        标签可以嵌套,但必须正确嵌套,而且一个xml文件有且仅有一个根标签,其他的标签都是这个标签的子标签或者孙标签
        XML中出现的所有换行与空格字符,都会当作标签内容来处理
  元素名称命名规范:
        区分大小写,例如,<P>和<p>是两个不同的标记。
        不能以数字或"_" (下划线)开头。
        不能以xml(或XML、或Xml 等)开头。
        不能包含空格。
        名称中间不能包含冒号(:)。
    属性
        一个元素可以有多个属性,每个属性的值都要用引号引起来
        <mytag name=”value” …/>
        命名规范跟元素相同
        属性是不允许重复的
    注释  
        <!--这是注释-->
        注释不能嵌套
    CDATA区 、特殊字符 
  转义字符:


    CDATA是Character Data的缩写
       作用:把标签当做普通文本内容;
       语法:<![CDATA[内容]]>
       写法提示:先写一对尖括号,再写一对方括号,再写一对方括号,再依次从最外层括号里面向内部添加内容:! CATAT 内容

    XML语法规则总结
        所有 XML 元素都须有关闭标签
        XML 标签对大小写敏感
        XML 必须正确地嵌套顺序
        XML 文档必须有根元素(只有一个)
        XML 的属性值须加引号
        特殊字符必须转义 --- CDATA
        XML 中的空格、回车换行会解析时被保留

3.XML约束之DTD

    XML约束:约束文档定义了在XML中允许出现的元素名称、属性及元素出现的顺序等等
    格式良好的XML:遵循XML语法的XML
    有效的XML:遵循约束文档的XML
  
    编写DTD的步骤:
    1.xml文档中需要出现哪些标签、个数是多少?6个
        <!ELEMENT 元素名称  元素类型>
    2.查询xml元素中,类型是什么.
        简单or复杂
    3.需要在xml中引入dtd.

Xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE persons SYSTEM "persons.dtd">
<persons>
	<person>
		<name>张三</name>
		<age>25</age>
		<money>300</money>
	</person>
	<person>
		<name>李四</name>
		<age>38</age>
		<money>600</money>
	</person>
</persons>
DTD文件:
<!ELEMENT persons (person+)>
<!ELEMENT person (name,age,money)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT money (#PCDATA)>

4.DTD语法

    元素的定义
        语法:<!ELEMENT 元素名称  元素类型>
        元素的类型:
            #PCDATA:可解析的字符数据
            子元素: 
            EMPTY: 空元素
            ANY:任意元素

        子元素的次数
            +:一次或多次
            *:零次或多次
            ?:零次或一次
        子元素的顺序
            ,: 子元素出现必须按照顺序.
            |: 子元素出现是或的关系.
    属性的定义: attribute--属性 
        语法:<!ATTLIST 元素名称 属性名称 属性类型 属性约束>
            * <!ATTLIST 书 出版社 CDATA #REQUIRED>

        属性类型:
            CDATA:字符数据(字符串)
            枚举:枚举类型
            ID:标识是唯一

        属性约束:
            #REQUIRED:属性必须出现.
            #IMPLIED:属性是可选的.
            #FIXED:属性采用固定值.
            默认值: 
    实体的定义
        语法:<!ENTITY 实体名称 实体值>
        <!ENTITY bookname "葵花宝典">


使用JAXP解析开发包的DOM解析XML

/**
 * JAXP的方式解析XML
 * 
 * @author Administrator
 * 
 */
public class JAXPTest {
	@Test
	/**
	 * 单元测试的方法:必须是public void  方法名 () 方法中不能有参数.
	 * 1.对xml进行查询。获得第一本书的作者节点<作者>春哥</作者> 
	 */
	public void demo1() throws Exception {
		/**
		 * 1.创建解析器工厂 2.由解析器工厂 来 创建解析器 3.通过解析器解析XML文档. --- Document
		 * 4.通过Document对象获得想去操作的节点.
		 */
		// 创建解析器工厂.
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		// 由工厂创建解析器
		DocumentBuilder builder = factory.newDocumentBuilder();
		// 解析XML。
		Document document = builder.parse("src/book.xml");
		// 通过Document对象获得想去操作的节点.、
		NodeList nodeList = document.getElementsByTagName("作者");
		Node node = nodeList.item(1);
		String value = node.getTextContent();
		System.out.println(value);
	}

	/**
	 * 2.在第一本书的下面 添加一个作者节点 <作者>曾哥</作者> 
	 * 	* 1.创建解析器工厂 
	 *   2.由解析器工厂 来 创建解析器
	 *   3.通过解析器解析XML文档. --- Document 
	 *   4.创建一个节点<作者> 添加文本内容 曾哥. 5.找到第一本书的节点。 6.给书的节点
	 * 添加一个子节点.
	 * 
	 */
	@Test
	public void demo2() throws Exception {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.parse("src/book.xml");
		// 创建一个作者节点:
		Element author = document.createElement("作者");
		// 设置内容
		author.setTextContent("曾哥");
		// 找到第一本书
		Node node = document.getElementsByTagName("书").item(0);
		// 项第一本书下 添加一个节点.
		node.appendChild(author);
		// 回写XML --- 将内存中的树形结构 写回到 XML中  (了解)
		TransformerFactory tFactory = TransformerFactory.newInstance();
		Transformer transformer = tFactory.newTransformer();
		transformer.transform(new DOMSource(document), new StreamResult(
				"src/book.xml"));

	}
	
	/**
	 * 3.在指定的位置添加节点。在<作者>春哥</作者>之前添加一个 <作者>汪峰</作者>
	 */
	@Test
	public void demo3() throws Exception {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.parse("src/book.xml");
		
		// 创建一个节点  给节点 添加一个文本内容
		Element author = document.createElement("作者");
		author.setTextContent("汪峰");
		// 先找到 春哥的 作者的节点。
		Node node = document.getElementsByTagName("作者").item(0);
		// 找到其父节点 
		node.getParentNode().insertBefore(author, node);
		
		
		TransformerFactory tFactory = TransformerFactory.newInstance();
		Transformer transformer = tFactory.newTransformer();
		transformer.transform(new DOMSource(document), new StreamResult(
				"src/book.xml"));
		
	}
	
	/**
	 * 4.修改文本内容.<作者>汪峰</作者>  改成 <作者>章子怡</作者>
	 */
	@Test
	public void demo4()throws Exception{
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.parse("src/book.xml");
		
		// 找到汪峰节点.
		Node node = document.getElementsByTagName("作者").item(0);
		node.setTextContent("章子怡");
		
		TransformerFactory tFactory = TransformerFactory.newInstance();
		Transformer transformer = tFactory.newTransformer();
		transformer.transform(new DOMSource(document), new StreamResult(
				"src/book.xml"));
	}
	
	/**
	 * 5.删除章子怡的作者节点.
	 */
	@Test
	public void demo5()throws Exception{
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.parse("src/book.xml");
		
		// 找到汪峰节点.
		Node node = document.getElementsByTagName("作者").item(0);
		node.getParentNode().removeChild(node);
		
		TransformerFactory tFactory = TransformerFactory.newInstance();
		Transformer transformer = tFactory.newTransformer();
		transformer.transform(new DOMSource(document), new StreamResult(
				"src/book.xml"));
	}
	
	/**
	 * 扩展: 遍历所有的节点名称
	 */
	@Test
	public void demo6()throws Exception{
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.parse("src/book.xml");
		// 调用list的方法
		list(document);
	}

	private void list(Node node) {
		// 判断Node是否是Element类型的
		if(node.getNodeType() == Node.ELEMENT_NODE){
			System.out.println(node.getNodeName());
		}
		// 获得所有的孩子节点
		NodeList nodeList = node.getChildNodes();
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node n = nodeList.item(i);
			// 递归
			list(n);
		}
	}
	
	/**
	 * 7.操作节点的属性.获得第一本书的出版社.
	 */
	@Test
	public void demo7()throws Exception{
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.parse("src/book.xml");
		
		// 找到了第一本书
		Node node = document.getElementsByTagName("书").item(0);
		// 如果父类没有这个方法  可以 转成 子类对象.
		Element element = null;
		if(node.getNodeType() == Node.ELEMENT_NODE){
			element = (Element) node;
		}
		System.out.println(element.getAttribute("出版社"));
	}
}

5.SAX解析

    在使用 DOM 解析 XML 文档时,需要读取整个 XML 文档,在内存中构架代表整个 DOM 树的Doucment对象,从而再对XML文档进行操作。此种情况下,如果 XML 文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出
    SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会文档进行操作。


    步骤:

        使用SAXParserFactory创建SAX解析工厂
            SAXParserFactory spf = SAXParserFactory.newInstance();
        通过SAX解析工厂得到解析器对象
            SAXParser sp = spf.newSAXParser();
        通过解析器对象解析xml文件
            xmlReader.parse("book.xml“,new XMLContentHandler());
        这里的XMLContentHandler 继承 DefaultHandler

使用JAXP解析开发包的SAX解析XML

public class SAXTest {
	@Test
	public void demo1() throws Exception {
		/**
		 * 1.创建解析器工厂 
		 * 2、由工厂创建解析器 
		 * 3.解析xml文档。 --- 绑定一个处理器
		 */
		SAXParserFactory factory = SAXParserFactory.newInstance();
		SAXParser parser = factory.newSAXParser();
		// 解析xml --- 绑定处理器
		parser.parse("src/book.xml", new MyDefaultHandler());
	}
}

class MyDefaultHandler extends DefaultHandler {
	private boolean flag = false;
	private int idx = 1;

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		if ("作者".equals(qName)) {
			flag = true;
		}
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		if (flag && idx == 2) {
			System.out.println(new String(ch, start, length));
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		if ("作者".equals(qName)) {
			flag = false;
			idx++;
		}
	}

}

6.dom4j解析xml

    DOM4j中,获得Document对象的方式有三种:
    1.读取XML文件,获得document对象            
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("input.xml"));
    2.解析XML形式的文本,得到document对象.
        String text = "<members></members>";
        Document document = DocumentHelper.parseText(text);
    3.主动创建document对象.
        Document document = DocumentHelper.createDocument()
        //创建根节点
        Element root = document.addElement("members");

    将文档写入XML文件:

    1.文档中全为英文,不设置编码,直接写入的形式.

    XMLWriter writer = new XMLWriter(new FileWriter("output.xml"));  writer.write(document);

    writer.close();
    2.文档中含有中文,设置编码格式写入的形式. OutputFormat format = OutputFormat.createPrettyPrint();

    // 指定XML编码                   
    format.setEncoding("GBK");

    XMLWriter writer = new XMLWriter(newFileWriter("output.xml"),format);

    writer.write(document);

    writer.close();

    Dom4j指定位置插入节点

    1.得到插入位置的节点列表(list)
    2.调用list.add(index,elemnent),由index决定element的插入位置。
    Element元素可以通过DocumentHelper对象得到。示例代码:


        Element aaa = DocumentHelper.createElement("aaa");
        aaa.setText("aaa");
        List list = root.element("书").elements();
        list.add(1, aaa);
        //更新document

        ....

public class Dom4JTest {
	@Test
	/**
	 * 1.查询 <作者>曾哥</作者> 节点.
	 */
	public void demo1() throws Exception {
		// 创建解析器
		SAXReader reader = new SAXReader();
		// 解析XML
		Document document = reader.read("src/book.xml");
		// 获得跟节点
		Element root = document.getRootElement();
		Element author = (Element) root.element("书").elements("作者").get(0);

		System.out.println(author.getText());
	}

	/**
	 * 2.修改<作者>曾哥</作者> 改为 峰哥
	 */
	@Test
	public void demo2() throws Exception {
		SAXReader reader = new SAXReader();
		Document document = reader.read("src/book.xml");
		Element root = document.getRootElement();
		// 找到具体的节点 修改
		Element author = (Element) root.element("书").elements("作者").get(1);
		author.setText("峰哥");
		// 回写XML
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding("UTF-8");
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),
				format);
		writer.write(document);
		writer.close();
	}

	/**
	 * 3.添加一个节点。
	 */
	@Test
	public void demo3() throws Exception {
		SAXReader reader = new SAXReader();
		Document document = reader.read("src/book.xml");
		Element root = document.getRootElement();

		// 添加节点
		// 找到第一本书
		root.element("书").addElement("作者").setText("张艺谋");

		// 回写XML
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding("UTF-8");
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),
				format);
		writer.write(document);
		writer.close();
	}

	/**
	 * 4.在指定的位置插入 创建元素: DocumentHelper.createElement("元素").setText();
	 * 找到第一个书.Element book = root.element("书") List list = book.elements();
	 * list.add();
	 */

	/**
	 * 5.删除  <作者>张艺谋</作者>
	 */
	@Test
	public void demo5() throws Exception  {
		SAXReader reader = new SAXReader();
		Document document = reader.read("src/book.xml");
		Element root = document.getRootElement();

		Element author = (Element) root.element("书").elements("作者").get(2);
		author.getParent().remove(author);
		// 回写XML
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding("UTF-8");
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),
				format);
		writer.write(document);
		writer.close();
	}
	
	@Test
	public void demo6()throws Exception {
		SAXReader reader = new SAXReader();
		Document document = reader.read("src/book.xml");
		// 获得的是多个节点
		// document.selectNodes(arg0)
		// 获得一个节点
		//document.selectSingleNode();
		
		// 查找书下的所有的作者节点
		/*List<Element> list = document.selectNodes("//作者");
		for (Element element : list) {
			System.out.println(element.getText());
		}*/
		
		Node node = document.selectSingleNode("//书[@id='b1']");
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值