XML解析——DOM解析

目前常用的XML解析技术有四种:DOM解析;SAX解析;JDOM;DOM4J

1. DOM解析

优点:适用于多次访问XML的应用程序;缺点:解析比较消耗资源

2. SAX解析

优点:资源占用少,内存消耗小

3. JDOM解析

优点:简化和XML之间的交互,使用速度快;缺点:限制了灵活性

4. DOM4J解析

优点:性能优异、功能强大、易用

本篇文章主要讲DOM解析,下篇文章讲解DOM4J解析的使用

一、DOM解析

目的一:将以下的XML文件通过解析用JAVA语言在控制台上输出

<?xml version="1.0" encoding="UTF-8"?>
<books> 
  <book> 
    <title>三国演义</title>  
    <author>罗贯中</author>  
    <price>30元</price> 
  </book>  
  <book> 
    <title>水浒传</title>  
    <author>施耐庵</author>  
    <price currencu="renminbi">35元</price> 
  </book>
</books>

先创建一个解析器工厂:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();//千万不能直接new

有了解析器工厂之后,生产出一个解析器:

DocumentBuilder db;//会报一个异常,捕捉一下
{
    try {
        db = factory.newDocumentBuilder();//也是不能直接new,要用解析器工厂去生产出来
    } catch (ParserConfigurationException e) {
        e.printStackTrace();
    }
}

有了解析器,就可以生产出一个DOM树了:

//获得DOM树
Document document;
{
    try {
        document = db.parse("E:\\IJ\\src\\XMLAdditional\\BookDOM.xml");//1、放文件2、也是不能直接new的哦
    } catch (SAXException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

用获得的DOM树.getElementsByTagName();可以根据元素名获得所需要的元素,返回的是一个指定元素名的节点的集合

NodeList bookList = document.getElementsByTagName("book");//得到book的集合,也就是《三国演义》、《水浒传》这两本书

通过遍历,得到元素集合中的一个

for (int i = 0; i < bookList.getLength(); i++) {
    Element bookElement = (Element) bookList.item(i);//得到其中一本,一本本的分析

String bookTitle = bookElement.getElementsByTagName("title").item(0).getFirstChild().getNodeValue();
String bookAuthor = bookElement.getElementsByTagName("author").item(0).getFirstChild().getNodeValue();
String bookPrice = bookElement.getElementsByTagName("price").item(0).getFirstChild().getNodeValue();

分析上述代码,以第一句为例。先通过getElementsByTagName()得到元素名称是title的集合,然后.iteam(),获得title集合的第0个位置(第0个位置是因为book标签下面的title集合中中title只有一个),是一个Element类型的,是单个元素,然后 .getFistChild()得到得到title下面的第一个子节点,最后通过 .getNodeValue()方法得到子节点的文本。通过这样的方法得到author和price。

根据XML中看,水浒传中的price有一个currencu的属性节点,三国演义这本书没有,所以还要通过判断将这个属性节点显示出来

先根据price集合中第0个位置的节点 .hasAttributes()判断是不是有属性;然后指定节点 .getAttribute()得到currencu的内容。

String currencuName="";
boolean currencuElement = bookElement.getElementsByTagName("price").item(0).hasAttributes();
if (currencuElement==true) {
    Element element= (Element) bookElement.getElementsByTagName("price").item(0);
    currencuName =element.getAttribute("currencu");
}

最后输出

System.out.println("书名:"+bookTitle+",作者"+bookAuthor+",价格"+bookPrice+currencuName);

到这里,就完成了输出XML中的显示文本信息的要求。

目的二:增加一个<book></book>,book中的内容为<title>西游记</title>;<author>吴承恩</author>;<price>40元</price>

<?xml version="1.0" encoding="UTF-8"?>
<books> 
  <book> 
    <title>三国演义</title>  
    <author>罗贯中</author>  
    <price>30元</price> 
  </book>  
  <book> 
    <title>水浒传</title>  
    <author>施耐庵</author>  
    <price currencu="renminbi">35元</price> 
  </book>
</books>

明确XML结构,books是根元素,也就是第一节点,book是第二节点,title,author,price是第三节点,西游记、吴承恩、40元是第四文本节点。

通过document.createElement创建节点,先创建所有需要添加的节点、(此时不需要设置节点的顺序关系,但是建议加注释或者按顺序写,便于理解)

//创建第二节结点
Element totalBook=document.createElement("book");
//创建第三节结点
Element bookTitle=document.createElement("title");
Element bookAuthor=document.createElement("author");
Element bookPrice=document.createElement("price");
//创建对应的文本节点
Text name=document.createTextNode("西游记");
Text author=document.createTextNode("吴承恩");
Text price=document.createTextNode("85");

创建完所有的节点之后,建立各个节点的层次关系,用Element的appendChild方法(建议按照顺序放,避免遗漏和混乱

//文本节点到三节
bookTitle.appendChild(name);
bookAuthor.appendChild(author);
bookPrice.appendChild(price);
//三节到二节
totalBook.appendChild(bookTitle);
totalBook.appendChild(bookAuthor);
totalBook.appendChild(bookPrice);
//二节到跟元素
Element books= (Element) document.getElementsByTagName("books").item(0);
books.appendChild(totalBook);

至此,增加完成,但是XML中还是原来的两本书,没有将西游记添加进去。

目的三:将增加在控制台的内容保存到XML中

和创建DOM解析器工厂相似,要保存就要先创建转换器工厂

//获得转换器工厂
TransformerFactory factory=TransformerFactory.newInstance();//不能new

获得工厂之后,可以设置缩进,确保保存到XML中的格式一致

//设置缩进
factory.setAttribute("indent-number",4);

获得转换器

//获得转换器
Transformer transformer=factory.newTransformer();//不能new

获得转换器之后可以设置属性(主要是允许缩进和编码格式)

//设置属性
transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT,"YES");

接下来就根据转换器 .transfom()进行转换,但是我们调方法的时候发现,这个时候需要传一个Source和Result类型的值进去。

获得Source类型的值:

DOMSource domSource=new DOMSource(document);

获得Sesult类型的值:

StreamResult result=new StreamResult(new OutputStreamWriter(new FileOutputStream("E:\\IJ\\src\\XMLAdditional\\BookDOM.xml"),"UTF-8"));

然后再进行转换

transformer.transform(domSource,result);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值