【JavaWeb】06 xml(二)解析方式:jaxp

xml解析

使用java代码。

js使用dom解析html:根据html的层级结构,在内存中分配一个树形结构,把html的标签,属性和文本都封装成对象:document、element、属性对象、文本对象、node节点对象。

xml的解析方式:dom和sax

  • dom:根据xml的层级结构在内存中分配一个树形结构,方便实现增删改操作,但当文件过大会造成内存溢出。
  • sax:采用时间驱动,边读边解析。从上到下,一行一行地解析,解析到某个对象,把对象名称返回。这种方式不会造成内存溢出、能方便地实现查询,但不能实现增删改操作。
  • 想要解析xml,首先需要解析器。不同的公司和组织提供了针对dom和sax方式的解析器,通过api方式。
    • sun公司:jaxp
    • dom4j组织:dom4j(常用)
    • jdom组织:jdom

jaxp的api的查看

jaxp是javase的一部分
jaxp解析器在jdk的javax.xml.parsers包里面。

四个类:分别是针对dom和sax解析使用的类。

dom

DocumentBuilder和DocumentBuilderFactory

  • DocumentBuilder:解析器类
    • 该类是一个抽象类,不能new对象。
    • 此类的实例可以从DocumentBuilderFactory.newDocumentBuilder()方法获取
    • parse("xml路径")可以解析xml,返回是Document整个文档
      返回的document是一个接口,父接口是Node,如果在document里面找不到想要的方法,到Node里面去找。
      • document和Node里面的方法:getElementsByTagName、createElement、createTextNode、appendChild、removeChild、getParentNode
      • NodeList集合的方法
        getLength():得到集合长度(注意此处与javase不同,javase集合用size())
        item(int index):返回集合中第index个项
//遍历集合
for(int i=0;i<list.length();i++){
list.item(i);
}
  • DocumentBuilderFactory:解析器工厂
    • 这个类也是一个抽象类。用newInstance()获取DocumentBuilderFactory的实例

使用jaxp查询节点

举例:查询所有name元素的值

  1. 创建解析器工厂
  2. 根据解析器工厂创建解析器
  3. 解析xml返回document
  4. 用document的方法得到name集合
  5. 遍历集合得到元素和值 getTextContent()
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
DocumentBuilder db=bf.newDocumentBuilder();
Document d=db.parse("person.xml");
NodeList list=document.getElementsByTagName("name");
for(int i;i<list.length();i++){
	Node name0=list.item(i);
	//得到元素内容
	String s=name0.getTextContent();
	System.out.println(s);
}

使用jaxp添加节点

举例:在第一个name标签下添加<sex>nv</sex>

  1. 创建解析器工厂
  2. 根据解析器工厂创建解析器
  3. 解析xml返回document
  4. 得到name集合,item(0)得到第一个name
  5. 创建标签、文本,并把文本添加到sex标签
  6. 把sex标签添加到第一个name
  7. 回写xml(解析后节点的改变仅在内存中,需要回写到xml文件)
public static void addSex() throws Exception
{
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance()
DocumentBuilder db=dbf.newDocumentBuilder=();
Document d=db.parse("person.xml");
NodeList list=d.getElementByTagName("name");
Node name1=list.item(0);
//-------------------
Element sex1=document.createElement("sex");
Text text=document.createTextNode("nv");
sex1.appendChild(text1);
name1.appendChild(sex1);
//-------------------
TransformerFactory tff=TransformerFactory.newInstance();
Transformer tf=TransformerFactory.newTransformer();
tf.transform(new DOMSouce(d),new StreamResult("person.xml"));
}

使用jaxp修改节点

举例:修改第一个sex的值

  1. 创建解析器工厂
  2. 根据解析器工厂创建解析器
  3. 解析xml返回document
  4. 得到第一个sex元素
  5. 修改值 setTextContent
  6. 回写xml
public static void changeSex() throws Exception
{
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance()
DocumentBuilder db=dbf.newDocumentBuilder=();
Document d=db.parse("person.xml");
NodeList list=d.getElementByTagName("sex");
Node sex1=list.item(0);
//-------------------
sex1.setTextContent("nan");
//-------------------
TransformerFactory tff=TransformerFactory.newInstance();
Transformer tf=TransformerFactory.newTransformer();
tf.transform(new DOMSouce(d),new StreamResult("person.xml"));
}

使用jaxp删除节点

举例:删除第一个sex的值

  1. 创建解析器工厂
  2. 根据解析器工厂创建解析器
  3. 解析xml返回document
  4. 获取sex元素
  5. 获取sex父节点
  6. 使用removeChild()删除
  7. 回写xml
public static void delSex() throws Exception
{
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance()
DocumentBuilder db=dbf.newDocumentBuilder=();
Document d=db.parse("person.xml");
NodeList list=d.getElementByTagName("sex");
Node sex1=list.item(0);
//--------------------
p1=sex1.getParentNode();
p1.removeChild(sex1);
//--------------------
TransformerFactory tff=TransformerFactory.newInstance();
Transformer tf=TransformerFactory.newTransformer();
tf.transform(new DOMSouce(d),new StreamResult("person.xml"));

使用jaxp遍历节点

打印xml中所有元素名称

  1. 创建解析器工厂
  2. 根据解析器工厂创建解析器
  3. 解析xml返回document
  4. 得到根节点
  5. 获取子节点(递归)
private static void listAll(Node node)
{
//判断是元素类型时才打印!!!!
if(node.getNodeType()==node.ELEMENT_NODE)
System.out.println(node.getNodeName());
//获取一层子节点
NodeList list=node.getChildNodes();
for(int i=0;i<list.getLength();i++)
{
	Node node1=list.item(i);
	listAll(node1);//递归
}
}	

sax

SAXParser和SAXParserFactory

  • SAXParser:是抽象类,实例通过SAXParserFactory.newSAXParser()获得
    • parse(File f,DefaultHandler dh)
      • 两个参数:xml路径、事件处理器
  • SAXParserFactory:实例通过newInstance()得到

sax执行过程:

  1. 当解析到开始标签(<root><head><title>)的时候,自动执行startElement方法。其中的qname:返回名称
  2. 当解析到文本(<body>)时候,自动执行characters方法
  3. 当解析到结束标签(如</head>)时候,自动执行endElement方法

使用jaxp的sax方式解析xml

  1. 创建解析器工厂
  2. 创建解析器
  3. 执行parse方法
  4. 自己创建一个类,继承DefalultHandler
  5. 重写类里的三个方法:startElement、characters、endElement
public static void main(String[] args)throws Exception
{
SAXParserFactory spf=SAXParserFactory.newInstance();
SAXParser sp=spf.newSAXParser();
sp.parse("xml路径",new MyDefault())
}
class MyDefault extends DefaultHandler
{
此处右键>sourse>override选中三个方法导入
然后可以复写读取后的操作
}

使用jaxp的sax方式查询

此处有点迷…
举例:获取所有name元素的值

class MyDefault extends DefaultHandler
{
boolean flag=false;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
	if("name".equals(qName))
	flag=true;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
//flag为真,说明解析到了name元素,可以打印
	if(flag==true)
	System.out.println(new String (ch,start,length));
}	
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
//name结束,将flag设为false
	if("name".equals(qName))
	flag=false;
}
}

sax获取第一个元素

例:获取第一个name元素的值
定义一个成员变量idx=1,结束方法的时候idx++
在characters方法里设置判断if(flag==true&&idx=1)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值