java-web 之 第一讲 xml 文件

XML  Extensible Markup language: 可扩展的标记语言

1:文档格式   

1: 开始标签必须有一个对应的结束标签

2:空元素必须关闭

3:所有标签都区分大小写

4:所有标签都必须合理嵌套

5:所有标签的属性值都必须用 双引号 或者单引号 括起来  如<student name="zhangsan" age='18'>  哪怕不是字符串也必须加上单引号

2:文档标记

            

         


     主要有五个部分组成

A:XML 声明   --DTD:定义xml文件中元素和属性的规则及相互关系

外部DTD的引用:使用 PUBLIC 关键字来引用

类型为:  <!PUBLIC  根元素的名称 PUBLIC" DTD的名称 " " 外部DTD文件的URL ">

B:文档类型声明     

C:元素     元素内容包括   子元素字符数据字符引用实体引用CDATA字段:以 <![CDATA[ 内容 ]]>格式 主要是嵌入 java代码 如下:

<span style="white-space:pre">			</span><pre name="code" class="html"><span style="white-space:pre">			</span><?xml version="1.0">
<span style="white-space:pre">			</span><java>
<span style="white-space:pre">			</span><![CDATA[
<span>				</span>if(a>b && c<d)
<span>				</span>max=a;
<span style="white-space:pre">			</span>]]>
 

 D:注释      

  E:处理指令:允许文档中包含由应用程序来处理的指令  例如:

<span style="white-space:pre">		</span><?xml-stylesheet href="hello.css" type="text/css" ?>  <!-- xml-stylesheet  叫做处理指令的目标  指令必须在声明后 第一个元素前 -->
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">
</span>
3 一个xml 文档中可以包含许多元素和属性,我们使用其他人的文档或者在文档中引用DTD文件时,有可能碰到名称相同的元素,为了区分就需要引用命名空间

1:声明名称空间

第一种形式: <元素名  xmlns:prefixname="URL">  例如: <hr xmlns:hr="http://www.sunxin.org/hr">

第二种形式:<hr xmlns="http://www.sunxin.org/hr">

2:名称空间在元素中的使用

如果不通节点下的子元素名称相同,在不通节点下使用不影响名称区分  例如:

4 XML 文档的解析

DOM:文档对象模型  W3C 推荐的处理xml 文件解析的标准接口

SAX: Simple Api for Xml

这两种只定义了接口,如果想利用 DOM 或者 SAX 访问 xml  还需要一个实现了 DOM 或者SAX 的解析器   Apache的 Xerces 提供了 这两种的调用接口,访问xml 的话

只需要在应用程序中构造一个解析器实现类的对象

如:

<span style="white-space:pre">		</span>org.xml.sax.XMLReader reader = new org.apache.xerces.parsers.SAXParser();
<span style="white-space:pre">		</span>FileInputStream fis = new FileInputStream("user.xml");
<span style="white-space:pre">		</span>InputSource in = new InputSource(fis);
<span style="white-space:pre">		</span>reader.setContentHandler(new MyContentHandler());
<span style="white-space:pre">		</span>reader.parse(in);


  1: 使用DOM 解析XML

a: DOM 解析模型

核心概念就是节点,定义了一个 Node 接口,表示文档树中的一个节点,并且从这个接口派生出更多的具体接口

如: Document :表示整个文档

Element  : 表示XML 中的元素

Attr: 表示元素属性

 Node 中的主要方法:

     String:  getNodeName() -- 返回节点名称getNodeType() -- 返回节点类型     getNodeValue() -- 返回节点值hasChildNodes()-- 是否有子节点

     NodeList:getChildNodes()  返回该节点所有子节点

    Node:    getFirstChild() -- 返回第一个子节点       getLastChild()-- 返回最后一个子节点    getParentNode()-- 返回该节点的父节点

     Document: getOwnerDocument() -- 返回该节点所属的 Document 对象

 NamedNodeMap:  getAttributes() -- 返回该节点所有的属性


b: DOM 解析器工厂

在 javax.xml.parsers 包中,定义了 DOM 解析器工厂类 DocumentBuilderFactory ,用于产生DOM 解析器,这是个抽象类,提供静态方法 newInstance() 

这样采用JAXP 编程可以任意更换解析器,newInstance() 通过下面三种途径找到解析器厂商给出的工厂类

(1) : 利用 System.setProperty("javax.xml.parsers.DocumentBuilderFactory","org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");

注意 ---- 不要在程序中直接设置解析工厂类 不然后期更换需要修改程序

(2): java.exe  中  通过 java -Djavax.xml.parsers.DocumentBuilderFactory=oracle.xml.jaxp.JXDocumentBuilderFactoryDOMTest

(3): 可以在 jdk 的 jre/lib 下建立 文件 jaxp.properties  配置要使用的工厂类

java x.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl  后期只需要修改这个配置文件即可


创建过程为:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  // 得到具体厂商的工厂类

DocumentBuilder db = factory.newDocumentBuilder(); // 得到具体厂商的DOM 解析器对象

Document d = db.parse(File f) // 获取整个文档的Document 对象  参数也可传  InputStream

// 注意javax.xml.parsers 中定义了一个错误类 FactoryConfigurationError 类和异常类 ParserConfigurationException 来抓取错误信息或异常



节点类型以及在DOM API中对应的接口图:

   

c: DOM 解析文档实例

(1) 文档节点:文档树的根节点,也是文档中处理其他节点的父节点  但并不是根元素,因为xml中指令 注释等可以出现在根元素以外,根元素只是

文档节点的子节点。所以 Document 中有个方法为 Element  e = Document.getDocumentElement()

同时还有创建各种节点的方法

1:创建 元素属性  Attr createAttrbute(String name)

2: 创建节点  Element creeateElement(String name)

对节点操作的方法:

1:Element getElementById(String elementID)   通过给定的ID来查找对应的元素

2: NodeList getElementByTagName(String name)  通过给定的name 返回所有的 元素集合

(2) 元素节点Element : 唯一能够拥有属性的节点类型  通常其拥有子元素和文本节点

String getAttribute(String name)  返回该元素的值

Attr  getArributeNode(String name)  通过属性的名称得到属性的节点  删除为 remove

(3) 文本节点 Text: 只包含文本内容的节点

例如: 如果在 student节点上调用getChildNodes() 返回的NodeList 包含五个节点, 空白 换行 空格3个 4)属性节点 Attr:代表了元素的属性


 解析例子 --  第一个实例:-------------------------------------------------------------------------------- 


XML 文件:

<?xml version="1.0" encoding="GB2312"?>
<?xml-stylesheet type="text/xsl" href="student.xsl"?>
<students>
<student sn="1">
<name>张三</name>
<age>12</age>
</student>
<student sn="2">
<name>李四</name>
<age>13</age>
</student>
<student sn="3">
<name>王五</name>
<age>14</age>
</student>
<student sn="4">
<name>赵六</name>
<age>15</age>
</student>
</students>



package com.tide.servlet;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;


import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class Test {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();

System.out.println(df.getClass().getName());// 解析器工厂类
try {
// 获取解析器工厂类的实例
DocumentBuilder db = df.newDocumentBuilder();

System.out.println(db.getClass().getName());  // dom解析器类名
Document d = (Document) db.parse("test.xml");    // 这里解析XML 文档
NodeList nl = d.getElementsByTagName("student");
int len = nl.getLength();
for(int m = 0;m<len;m++){
Element el = (Element) nl.item(m);

Node node_name = (Node) el.getElementsByTagName("name").item(0);
Node node_age = (Node) el.getElementsByTagName("age").item(0);
String name = node_name.getFirstChild().getNodeValue();
String age = node_age.getFirstChild().getNodeValue();
System.out.println(name+" -- "+age);

}

} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


}

第一个实例:-------------------------------------------------------------------------------- end


第二个实例: 添加 删除 和修改节点



public class Test2 {


/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
try{
DocumentBuilder db = df.newDocumentBuilder();
Document d = db.parse("test.xml");
//------------- 添加节点  创建一个学生信息的各元素点
Element elstu = d.createElement("student");
Element slname = d.createElement("name");
Element slage = d.createElement("age");

// 创建 student 元素的sn 属性节点
Attr attr = d.createAttribute("sn");
attr.setValue("5");
elstu.setAttributeNode(attr);  // 为 stu 元素添加sn 的属性节点

// 创建代表学生信息的文本节点
Text tName = d.createTextNode("孙七");
Text tAge = d.createTextNode("17");

//将文本节点添加为对应的元素的子节点上  name = 孙七
slname.appendChild(tName);
slage.appendChild(tAge);

// 将 name  age 添加为student 节点的子节点上
elstu.appendChild(slname);
elstu.appendChild(slage);

// 获取文档根元素
Element elRoot = d.getDocumentElement();
// 将 student 节点添加为 根元素的子节点
elRoot.appendChild(elstu);
NodeList list = d.getElementsByTagName("student");

// 删除节点
Node del = list.item(0);
del.getParentNode().removeChild(del);

// 修改节点    注意:NodeList 是动态的,前面删除后 索引为0 的节点是原来索引为1 的节点
Element update = (Element) list.item(0);
Node updateAge = update.getElementsByTagName("age").item(0);
updateAge.getFirstChild().setNodeValue("50");

// 输出信息
for(int m = 0;m<list.getLength();m++){
Element el = (Element) list.item(m);
System.out.println("编号: "+el.getAttribute("sn"));
Node nodeName = el.getElementsByTagName("name").item(0);
String name = nodeName.getFirstChild().getNodeValue();
Node nodeAge = el.getElementsByTagName("age").item(0);
String age = nodeAge.getFirstChild().getNodeValue();
System.out.println("姓名:"+name);
System.out.println("年龄:"+age);
System.out.println("------------");
}


}catch(Exception e){
e.printStackTrace();
}
}

}

结果为 : 张三被删除  李四年龄为改为 50  新增了孙七


// 如果要将输出结果保存到 xml 的话  需要XSL 转换  注意 这里的XSL转换是没有使用任何 XSLT 样式表的恒等转换,即直接输出复制源到对象中
// 首先 利用文档节点  创建一个 DOM 输出源
DOMSource source = new DOMSource(d);
StreamResult result = new StreamResult(new File("test22.xml"));
// 得到转换器工厂类的实例
TransformerFactory fac = TransformerFactory.newInstance();
// 创建一个新的转换器 将DOM 输入源内容复制到结果文档中
Transformer tf = fac.newTransformer();
tf.transform(source, result);

第二个实例 -----------------------------------------------------------------------------------------end


后期有 SAX 解析器工厂来解析 xml  和 JDOM 解析xml 以及 dom4j 来进行解析   dom4j 性能优越且灵活性较大  Hibernate 就是用的 dom4j 解析    下期将重点讲解 dom4j 解析


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值