当前位置: 首页 > 工具软件 > XMLDB > 使用案例 >

XML文件生成和解析

罗业
2023-12-01

                  使用Dom生成xml文件和解析xml文件

   xml这种文件格式在很多时候都是很适合我们用来存取数据的,所以利用程序来生成xml文件和解析xml文件就显得比较重要了。在dom中是把每一个元素都看做是一个节点Node的,所有页面上的属性、元素等都是继承自Node的,所以当获取到的是一个Node,而你知道它实际的类型并需要使用的时候就可能会需要进行类型转换了。

Element root = document.getDocumentElement();//获取根节点

下面是代码:

1、生成xml:

package geneXmlByDom;
import java.io.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class BuildXml {
public  BuildXml() throws Exception {  
        //step1:获得一个DocumentBuilderFactory  
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
        //step2:获得一个DocumentBuilder  
        DocumentBuilder db = factory.newDocumentBuilder();  
        //step3:新建一个Document对象  
        Document document = db.newDocument();  
        //step4:创建一个根节点  
        Element rootElement = document.createElement("Persons");  
        for (int i=0;i<5;i++) {  
            //step5:创建一个节点  
            Element person = document.createElement("person");  
            //step6:为该节点设定属性  
            person.setAttribute("id", "id_"+i);  
            Element name = document.createElement("name");  
            //为节点设定文本内容  
            name.setTextContent("name_"+i);  
            Element address = document.createElement("address");  
            address.setTextContent("address_"+i);  
            Element email = document.createElement("email");  
            email.setTextContent("email_"+i);  
            person.appendChild(name);  
            person.appendChild(address);  
            person.appendChild(email);  
            //step7:为某一元素节点设立子节点  
            rootElement.appendChild(person);  
        }  
        //step8:把刚刚建立的根节点添加到document对象中  
        document.appendChild(rootElement);  
        //step9:获得一个TransformerFactory对象  
        TransformerFactory transformerFactory = TransformerFactory.newInstance();  
        //step10:获得一个Transformer对象  
        Transformer transformer = transformerFactory.newTransformer();  
        //step11:把document对象用一个DOMSource对象包装起来  
        Source xmlSource = new DOMSource(document);  
        //step12:建立一个存储目标对象  
        Result outputTarget = new StreamResult(new File("persons.xml"));  
        //step13:生成相应的xml文件  
        transformer.transform(xmlSource, outputTarget);  
    }  
public static void main(String[] args) throws Exception {
BuildXml buildxml=new BuildXml();
}
}

2、生成的xml文件是这个样子

<?xml version="1.0" encoding="UTF-8" standalone="no"?>  
<Persons>  
    <person id="id_0">  
        <name>name_0</name>  
        <address>address_0</address>  
        <email>email_0</email>  
    </person>  
    <person id="id_1">  
        <name>name_1</name>  
        <address>address_1</address>  
        <email>email_1</email>  
    </person>  
    <person id="id_2">  
        <name>name_2</name>  
        <address>address_2</address>  
        <email>email_2</email>  
    </person>  
    <person id="id_3">  
        <name>name_3</name>  
        <address>address_3</address>  
        <email>email_3</email>  
    </person>  
    <person id="id_4">  
        <name>name_4</name>  
        <address>address_4</address>  
        <email>email_4</email>  
    </person>  
</Persons>  


在进行输出写到文件的时候可以设置一些Transformer输出的参数,如xml的编码,或者输出形式等。

transformer.setOutputProperty("encoding", "UTF-8");//设定文档编码,属性也可以使用OutputKeys的静态常量属性设定  

transformer.setOutputProperty(OutputKeys.METHOD, "xml");//输出方式,可以是xml、html和text  

下面的解析也是基于这个文件的。

3、解析xml:

package geneXmlByDom;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class parseXmlByDom {
public parseXmlByDom() throws Exception {  
        //step1:获得DocumentBuilderFactory  
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
        //step2:获得DocumentBuilder  
        DocumentBuilder db = factory.newDocumentBuilder();  
        //step3:把需要解析的xml文件加载到一个document对象中  
        Document document = db.parse("persons.xml");  
        //获取所有名称为person的元素  
        NodeList nodeList = document.getElementsByTagName("person");  
        for (int i=0;i<nodeList.getLength();i++) {  
            //因为这里我知道它就是一个Element对象,所以进行了强转  
            Element person = (Element)nodeList.item(i);  
            //获得Element对象的属性  
            String id = person.getAttribute("id");  
            //因为这里我知道只有一个对象,所以就直接item(0)了,  
            //因为Dom是把每个对象都看做是一个节点的,所以如果在item(0)的时候直接取getNodeValue()是取不到值的,  
            //只有是TextNode的时候用那个方法才可以取到值,如果想直接取值就用getTextContent()  
            String name = person.getElementsByTagName("name").item(0).getTextContent();  
            String address = person.getElementsByTagName("address").item(0).getTextContent();  
            String email = person.getElementsByTagName("email").item(0).getTextContent();  
            /*String name1=person.getNodeName();
            String content=person.getTextContent();
            System.out.println("name1="+name1+"-content="+content+"\n");*/
            System.out.println(" id = "+id+" \r\n name = "+name+" \r\n address = "+address+" \r\n email = "+email);  
            System.out.println("-------------------------------------");     
        }   
    }  
public static void main(String[] args) throws Exception {
parseXmlByDom buildxml=new parseXmlByDom();
}
}

4、解析后输出的结果:

 id = id_0   

 name = name_0   

 address = address_0   

 email = email_0  

-------------------------------------  

 id = id_1   

 name = name_1   

 address = address_1   

 email = email_1  

-------------------------------------  

 id = id_2   

 name = name_2   

 address = address_2   

 email = email_2  

 

 

                           JDOM使用指南

1、Jdom的下载和安装  

JDOM是一个开源项目,它基于树型结构,利用纯JAVA的技术对XML文档实现解析、生成、序列化以及多种操作。JDOM 直接为JAVA编程服务。它利用更为强有力的JAVA语言的诸多特性(方法重载、集合概念以及映射),把SAX和DOM的功能有效地结合起来。在使用设计上尽可能地隐藏原来使用XML过程中的复杂性。利用JDOM处理XML文档将是一件轻松、简单的事。

    Jdom的下载可至jdom官网http://www.jdom.org,目前最新的是2.05,不过要是怀旧用了jdk1.2到1.4,也可以用1.1.3,使用两个版本,区别只是导出包的时候,包名是org.jdom还是org.jdom2;下载后,将jdom.jar(2.05版为jdom-2.0.5.jar,解压后即可见到;1.1.3版为jdom-1.1.3.jar,解压后在build目录下),将jar文件放到一个可靠的位置,相对专业的位置是classpath,比如楼主参考放在了C:\Program Files\Java\jre6\lib\ext,实际上,这个位置可以任意,因为是需要添加jar文件路径工场的build path的,不过编程也需要专业一点,以及方便归档,所以建议还是放到lib/ext。至此,安装完毕。

2、JDOM 包概览

JDOM是由以下几个包组成的

org.jdom                包含了所有的xml文档要素的java类

org.jdom.adapters         包含了与dom适配的java类

org.jdom.filter            包含了xml文档的过滤器类

org.jdom.input            包含了读取xml文档的类

org.jdom.output           包含了写入xml文档的类

org.jdom.transform        包含了将jdom xml文档接口转换为其他xml文档接

org.jdom.xpath            包含了对xml文档xpath操作的类三、JDOM 类说明

3、生成xml文档

package xml;
import java.io.*;
import org.jdom2.*;
import org.jdom2.output.*;
public class WriteXML {
public void BuildXML() throws Exception
    {
        Element root,student,number,name,age;
        root = new Element("student-info"); //生成根元素:student-info   
        student = new Element("student");      //生成元素:student,该元素中将包含元素number,name,age
        number = new Element("number");
        name = new Element("name");
        age = new Element("age");
        Document doc = new Document(root);    //将根元素植入文档doc中
        number.setText("001");
        name.setText("lnman");
        age.setText("24");
        student.addContent(number);
        student.addContent(name);
        student.addContent(age);
        root.addContent(student);
        Format format = Format.getCompactFormat();
        format.setEncoding("gb2312");           //设置xml文件的字符为gb2312
        format.setIndent("    ");               //设置xml文件的缩进为4个空格
        XMLOutputter XMLOut = new XMLOutputter(format);//在元素后换行,每一层元素缩排四格
        XMLOut.output(doc, new FileOutputStream("studentinfo.xml"));    
    }
    public static void main(String[] args) throws Exception
    {
        WriteXML w = new WriteXML();
        System.out.println("Now we build an XML document .....");
        w.BuildXML();
        System.out.println("finished!");
    }
}


生成的xml文档为:

<?xml version="1.0" encoding="gb2312"?>
<student-info>
  <student>
    <number>001</number>
    <name>lnman</name>
    <age>24</age>
  </student>
</student-info>


4、读取xml文档

package xml;
import org.jdom2.output.*;
import org.jdom2.input.*;
import org.jdom2.*;
import java.io.*;
import java.util.*;
public class ReadXML {
public static void main(String[] args) throws Exception
    {     
        SAXBuilder builder = new SAXBuilder();
        Document read_doc = builder.build("studentinfo.xml");
        Element stu = read_doc.getRootElement();
        List list = stu.getChildren("student");
        for(int i = 0;i < list.size();i++)
        {
            Element e = (Element)list.get(i);
            String str_number = e.getChildText("number");
            String str_name = e.getChildText("name");
            String str_age = e.getChildText("age");
            System.out.println("---------STUDENT--------------");
            System.out.println("NUMBER:" + str_number);
            System.out.println("NAME:" + str_name);
            System.out.println("AGE:" + str_age);
            System.out.println("------------------------------");
            System.out.println();
        }       
    }
}


5、方法

(1)、创建Document

/**
 * 创建xml元素
 */
@Test
public void createDoc() {
    Document doc = null;
    //method 1、创建一个Doc文档,添加一个元素root
    doc = new Document(new Element("root"));
    print(doc);
    //method 2、创建一个Doc文档,添加一个元素root,设置root元素的节点文本
    doc = new Document(new Element("root").setText("this is a root el"));
    print(doc);
    //method 3、创建一个Doc文档,添加一个元素root,设置root元素的节点文本且添加一个属性id,值为110
    Element root = new Element("root");
    root.setText("this is a root el");
    root.setAttribute("id", "110");
    doc.setRootElement(root);
fail("method 3: \n" + out.outputString(doc));
 //method 4、创建一个Doc文档,添加一个元素root,设置root元素的节点文本
    doc = new Document();
    doc.addContent(new Element("root").setText("this is a root el"));
    fail("method 4: \n" + out.outputString(doc));
    fail(doc.toString());
}


* new Document可以创建一个doc文档

当给Document传递一个Element参数时,这个Element就是根元素;

当调用Document的setRootElement方法时,可以设置当前Doc的根元素;

当调用doc的addContent的时候,添加的元素将会是根元素;

doc = new Document(new Element("root").setText("this is a root el"));

上面就创建了一个doc,根元素是root,root节点的内容是this is a root el;

注意setText方法返回的对象是当前Element,类似是StringBuffer的append方法;

* new Element()可以创建一个元素

如果传递参数那么这个参数将会是元素节点的名称;

Element的setText方法可以设置元素的文本值;

Element root = new Element("root");

root.setText("this is a root el");

创建一个节点名称为root的元素,文本是this is a root el

* setAttribute()可以设置某个具体节点的属性值

root.setAttribute("id", "110");

给root节点添加一个id,值为110

* addContent添加注释

root .addContent(new Comment("注释"));

在root元素下添加一个注释;

addContent是向元素中添加内容,而setContent是设置内容;

* setText设置元素文本内容

root.setText("this is a root el");

同样

root. setContent(new Text("this is text"))

同样

root.addContent("this is text");

下面用上面的这些方法,创建一篇XML文档。文档内容如下:

/**

(2)、创建xml文档 

<?xml version="1.0" encoding="UTF-8"?>
    <car vin="123fhg5869705iop90">
      <!--Description of a car-->
      <make>Toyota</make>
      <model>Celica</model>
      <year>1997</year>
      <color>green</color>
      <license state="CA">1ABC234</license>
    </car>

 */

@Test
public void createXMLDoc() {
    //创建一个car的元素
    Element carEl = new Element("car");
    //创建vin属性,并设置值
    carEl.setAttribute("vin", "123fhg5869705iop90");
    //创建注释
    carEl.addContent(new Comment("Description of a car"));
    //创建一个make元素,设置文本内容
    carEl.addContent(new Element("make").setText("Toyota"));
    //创建一个model元素,添加一个文本元素
    carEl.addContent(new Element("model").setContent(new Text("Celica")));
    //创建一个year元素,添加文本内容
    carEl.addContent(new Element("year").addContent("1997"));
    //创建一个color元素,文本内容是green
    carEl.addContent(new Element("color").setText("green"));
    //创建一个license的元素
    Element licenseEl = new Element("license");
    //为license元素添加文本内容
    licenseEl.addContent("1ABC234");
    //创建一个state的属性,值为CA
    licenseEl.setAttribute("state", "CA");
    //将licenseEl添加到根元素中
    carEl.addContent(licenseEl);
    //将car元素设置为根元素
    Document doc = new Document(carEl);
    print(doc);
    /*out = new XMLOutputter();
    try {
        out.output(doc, System.out);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

(3)、 读取XML文件的内容

 disk.xml文件内容如下:

  

<?xml version="1.0" encoding="UTF-8"?>
<HD>
    <disk name="C">
        <capacity>8G</capacity>
        <directories>200</directories>
        <files>1580</files>
    </disk>
    <disk name="D">
        <capacity>10G</capacity>
        <directories>500</directories>
        <files>3000</files>
    </disk>
    <disk2 name="E">
        <capacity>11G</capacity>
        <directories>50</directories>
        <files size="200" modifyDate="2011-08-3">
            <file>Java book</file>
            <file>Spring.txt</file>
            <file>strtus.doc</file>
        </files>
    </disk2>
    <files size="220">500</files>
</HD>

读取disk文件的内容,代码如下:

/**
 * <b>function:</b>读取xml文件中的元素
 * @author hoojo
 * @createDate 2011-8-4 下午04:54:17
 */
@Test
@SuppressWarnings("unchecked")
public void readXMLContent() {
    SAXBuilder builder = new SAXBuilder();//通过SAX解析器创建一个JDOM文档
    try {
        Document doc = builder.build(new File("file/disk.xml"));
        Element rootEl = doc.getRootElement();
        //获得所有子元素
        List<Element> list = rootEl.getChildren();
        //List<Element> list = rootEl.getChildren("disk");
        for (Element el : list) {
            //获取name属性值
            String name = el.getAttributeValue("name");
            //获取子元素capacity文本值
            String capacity = el.getChildText("capacity");
            //获取子元素directories文本值
            String directories = el.getChildText("directories");
            String files = el.getChildText("files");
            System.out.println("磁盘信息:");
            System.out.println("分区盘符:" + name);
            System.out.println("分区容量:" + capacity);
            System.out.println("目录数:" + directories);
            System.out.println("文件数:" + files);
            System.out.println("-----------------------------------");
        }
    } catch (JDOMException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}


* getChildren方法可以获取所有子元素

* getChildren(elName)可以获取所有名称为elName的子节点

* getAttributeValue可以获取指定属性的值

* getChildText可以获取子节点的文本值

 

                            DOM4J使用指南

1、DOM4J简介

Dom4j是一个易用的、开源的库,用于XML,XPath和XSLT。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。

它的主要接口都在org.dom4j这个包里定义:

Attribute Attribute     定义了XML的属性

Branch Branch        为能够包含子节点的节点如XML元素(Element)和文档

                    (Docuemnts)定义了一个公共的行为,

CDATA CDATA       定义了XML CDATA 区域

CharacterData         CharacterData是一个标识借口,标识基于字符的节点。

                    如CDATA,Comment, Text.

Comment            定义了XML注释的行为

Document            定义了XML文档

DocumentType        定义XML DOCTYPE声明

Element              定义XML 元素

ElementHandler       定义了 Element 对象的处理器

ElementPath          被 ElementHandler 使用,用于取得当前正在处理的路径

                    层次信息

Entity               定义 XML entity

Node               为所有的dom4j中XML节点定义了多态行为

NodeFilter           定义了在dom4j节点中产生的一个滤镜或谓词的行为

ProcessingInstruction  定义 XML 处理指令.

Text                定义XML 文本节点.

Visitor              用于实现Visitor模式.

XPath              在分析一个字符串后会提供一个XPath 表达式

要想弄懂这套接口,关键的是要明白接口的继承关系:

  interface java.lang.Cloneable

  interface org.dom4j.Node

  interface org.dom4j.Attribute

  interface org.dom4j.Branch

  interface org.dom4j.Document

  interface org.dom4j.Element

  interface org.dom4j.CharacterData

  interface org.dom4j.CDATA

  interface org.dom4j.Comment

  interface org.dom4j.Text

  interface org.dom4j.DocumentType

  interface org.dom4j.Entity

  interface org.dom4j.ProcessingInstruction

  一目了然,很多事情都清楚了。大部分都是由Node继承来的。知道这些关系,将来写程序就不会出现ClassCastException了。

2、读取并解析XML文档

  读写XML文档主要依赖于org.dom4j.io包,其中提供DOMReader和SAXReader两类不同方式,而调用方式是一样的。这就是依靠接口的好处。

// 从文件读取XML,输入文件名,返回XML文档

通过SAXReader类来解析XML文档的代码: 

  SAXReader reader = new SAXReader();

  Document document = reader.read(new File(“student.xml”));

通过DOMReader类来解析XML文档的代码

DocumentBuilderFactory adf=DocumentBuilderFactory .newInstance();

DocumentBuilder db=dbf.newDocumentBuilder();

org.w3.c.dom.Document Document=db.parse(new File(“student.xml”));

DOMReader domReader==new DOMReader();

Org.dom4j.Document doc=domReader.read(document);

  其中,reader的read方法是重载的,可以从InputStream, File, Url等多种不同的源来读取。得到的Document对象就代表了整个XML。

  根据本人自己的经验,读取的字符编码是按照XML文件头定义的编码来转换。如果遇到乱码问题,注意要把各处的编码名称保持一致即可。

3、取得Root节点

  读取后的第二步,就是得到Root节点。熟悉XML的人都知道,一切XML分析都是从Root元素开始的。

  public Element getRootElement(Document doc){

  return doc.getRootElement(); //返回根元素

  }

4、遍历XML树

  DOM4J提供至少3种遍历节点的方法:

  1) 枚举(Iterator)

  // 枚举所有子节点

  for ( Iterator i = root.elementIterator(); i.hasNext(); ) {

  Element element = (Element) i.next();

  // do something

  }

  // 枚举名称为foo的节点

  for ( Iterator i = root.elementIterator(foo); i.hasNext();) {

  Element foo = (Element) i.next();

  // do something

  }

  // 枚举属性

  for ( Iterator i = root.attributeIterator(); i.hasNext(); ) {

  Attribute attribute = (Attribute) i.next();

  // do something

  }

  2)递归

  递归也可以采用Iterator作为枚举手段,但文档中提供了另外的做法

  public void treeWalk() {

  treeWalk(getRootElement());

  }

  public void treeWalk(Element element) {

  for (int i = 0, size = element.nodeCount(); i < size; i++) {

  Node node = element.node(i);

  if (node instanceof Element) {

  treeWalk((Element) node);

  } else { // do something....

  }

  }

  }

  3) Visitor模式

  最令人兴奋的是DOM4J对Visitor的支持,这样可以大大缩减代码量,并且清楚易懂。了解设计模式的人都知道,Visitor是GOF设计模式之一。其主要原理就是两种类互相保有对方的引用,并且一种作为Visitor去访问许多Visitable。我们来看DOM4J中的Visitor模式(快速文档中没有提供)

  只需要自定一个类实现Visitor接口即可。

  public class MyVisitor extends VisitorSupport {

  public void visit(Element element){

  System.out.println(element.getName());

  }

  public void visit(Attribute attr){

  System.out.println(attr.getName());

  }

  }

  调用: root.accept(new MyVisitor())

  Visitor接口提供多种Visit()的重载,根据XML不同的对象,将采用不同的方式来访问。上面是给出的Element和Attribute的简单实现,一般比较常用的就是这两个。VisitorSupport是DOM4J提供的默认适配器,Visitor接口的Default Adapter模式,这个模式给出了各种visit(*)的空实现,以便简化代码。

  注意,这个Visitor是自动遍历所有子节点的。如果是root.accept(MyVisitor),将遍历子节点。我第一次用的时候,认为是需要自己遍历,便在递归中调用Visitor,结果可想而知。

5、XPath支持

  DOM4J对XPath有良好的支持,如访问一个节点,可直接用XPath选择。

  public void bar(Document document) {

  List list = document.selectNodes( //foo/bar );

  Node node = document.selectSingleNode(//foo/bar/author);

  String name = node.valueOf( @name );

  }

  例如,如果你想查找XHTML文档中所有的超链接,下面的代码可以实现:

  public void findLinks(Document document) throws DocumentException {

  List list = document.selectNodes( //a/@href );

  for (Iterator iter = list.iterator(); iter.hasNext(); ) {

  Attribute attribute = (Attribute) iter.next();

  String url = attribute.getValue();

  }

  }

6、字符串与XML的转换

  有时候经常要用到字符串转换为XML或反之,

  // XML转字符串

  Document document = ...;

  String text = document.asXML();

  // 字符串转XML

  String text = <name>James</name> </person>;

  Document document = DocumentHelper.parseText(text);

7、用XSLT转换XML

  public Document styleDocument(

  Document document,

  String stylesheet

  ) throws Exception {

  // load the transformer using JAXP

  TransformerFactory factory = TransformerFactory.newInstance();

  Transformer transformer = factory.newTransformer(

  new StreamSource( stylesheet )

  );

  // now lets style the given document

  DocumentSource source = new DocumentSource( document );

  DocumentResult result = new DocumentResult();

  transformer.transform( source, result );

  // return the transformed document

  Document transformedDoc = result.getDocument();

  return transformedDoc;

  }

8、创建XML

  一般创建XML是写文件前的工作,这就像StringBuffer一样容易。

  public Document createDocument() {

  Document document = DocumentHelper.createDocument();

  Element root = document.addElement(root);

  Element author1 =

  root

  .addElement(author)

  .addAttribute(name, James)

  .addAttribute(location, UK)

  .addText(James Strachan);

  Element author2 =

  root

  .addElement(author)

  .addAttribute(name, Bob)

  .addAttribute(location, US)

  .addText(Bob McWhirter);

  return document;

  }

9、文件输出

  一个简单的输出方法是将一个Document或任何的Node通过write方法输出

  FileWriter out = new FileWriter( foo.xml );

  document.write(out);

  如果你想改变输出的格式,比如美化输出或缩减格式,可以用XMLWriter类

  public void write(Document document) throws IOException {

  // 指定文件

  XMLWriter writer = new XMLWriter( new FileWriter( output.xml ) );

  writer.write( document );

  writer.close();

  // 美化格式

OutputFormat format = OutputFormat.createPrettyPrint();

format.setEncoding(“GBK”);

format.setIndex(“    ”)

  writer = new XMLWriter( System.out, format );

  writer.write( document );

  如何,DOM4J够简单吧,当然,还有一些复杂的应用没有提到,如ElementHandler等。如果你动心了,那就一起来用DOM4J。

10、DOM4J解析XML文件实例

package xml;
import java.io.File;  
import java.io.FileOutputStream;  
import java.io.OutputStreamWriter;  
import java.util.Iterator;  
import java.util.List;  
import org.dom4j.Attribute;  
import org.dom4j.Document;  
import org.dom4j.Element;  
import org.dom4j.io.OutputFormat;  
import org.dom4j.io.SAXReader;  
import org.dom4j.io.XMLWriter;  
public class Demo01 {
public void test() throws Exception {  
        // 创建saxReader对象  
        SAXReader reader = new SAXReader();  
        // 通过read方法读取一个文件 转换成Document对象  
        Document document = reader.read(new File("src/dom4j/sida.xml"));  
        //获取根节点元素对象  
        Element node = document.getRootElement();  
        //遍历所有的元素节点  
        listNodes(node);  
        // 获取四大名著元素节点中,子节点名称为红楼梦元素节点。  
        Element element = node.element("红楼梦");  
        //获取element的id属性节点对象  
        Attribute attr = element.attribute("id");  
        //删除属性  
        element.remove(attr);  
        //添加新的属性  
        element.addAttribute("name", "作者");  
        // 在红楼梦元素节点中添加朝代元素的节点  
        Element newElement = element.addElement("朝代");  
        newElement.setText("清朝");  
        //获取element中的作者元素节点对象  
        Element author = element.element("作者");  
        //删除元素节点  
        boolean flag = element.remove(author);  
        //返回true代码删除成功,否则失败  
        System.out.println(flag);  
        //添加CDATA区域  
        element.addCDATA("红楼梦,是一部爱情小说.");  
        // 写入到一个新的文件中  
        writer(document);  
    }  
    /**
     * 把document对象写入新的文件
     *  
     * @param document
     * @throws Exception
     */  
    public void writer(Document document) throws Exception {  
        // 紧凑的格式  
        // OutputFormat format = OutputFormat.createCompactFormat();  
        // 排版缩进的格式  
        OutputFormat format = OutputFormat.createPrettyPrint();  
        // 设置编码  
        format.setEncoding("UTF-8");  
        // 创建XMLWriter对象,指定了写出文件及编码格式  
        // XMLWriter writer = new XMLWriter(new FileWriter(new  
        // File("src//a.xml")),format);  
        XMLWriter writer = new XMLWriter(new OutputStreamWriter(  
                new FileOutputStream(new File("src//a.xml")), "UTF-8"), format);  
        // 写入  
        writer.write(document);  
        // 立即写入  
        writer.flush();  
        // 关闭操作  
        writer.close();  
    }  
    /**
     * 遍历当前节点元素下面的所有(元素的)子节点
     *  
     * @param node
     */  
    public void listNodes(Element node) {  
        System.out.println("当前节点的名称::" + node.getName());  
        // 获取当前节点的所有属性节点  
        List<Attribute> list = node.attributes();  
        // 遍历属性节点  
        for (Attribute attr : list) {  
            System.out.println(attr.getText() + "-----" + attr.getName()  
                    + "---" + attr.getValue());  
        }  
        if (!(node.getTextTrim().equals(""))) {  
            System.out.println("文本内容::::" + node.getText());  
        }
        // 当前节点下面子节点迭代器  
        Iterator<Element> it = node.elementIterator();  
        // 遍历  
        while (it.hasNext()) {  
            // 获取某个子节点对象  
            Element e = it.next();  
            // 对子节点进行遍历  
            listNodes(e);  
        }  
    }
    /**
     * 介绍Element中的element方法和elements方法的使用
     *  
     * @param node
     */  
    public void elementMethod(Element node) {  
        // 获取node节点中,子节点的元素名称为西游记的元素节点。  
        Element e = node.element("西游记");  
        // 获取西游记元素节点中,子节点为作者的元素节点(可以看到只能获取第一个作者元素节点)  
        Element author = e.element("作者");
        System.out.println(e.getName() + "----" + author.getText());
        // 获取西游记这个元素节点 中,所有子节点名称为作者元素的节点 。  
        List<Element> authors = e.elements("作者");  
        for (Element aut : authors) {  
            System.out.println(aut.getText());  
        }  
        // 获取西游记这个元素节点 所有元素的子节点。  
        List<Element> elements = e.elements();  
        for (Element el : elements) {  
            System.out.println(el.getText());  
        }  
    }
}  


sida.xml描述四大名著的操作

<?xml version="1.0" encoding="UTF-8"?>  
<四大名著>  
    <西游记 id="x001">  
        <作者>吴承恩1</作者>  
        <作者>吴承恩2</作者>  
        <朝代>明朝</朝代>  
    </西游记>  
    <红楼梦 id="x002">  
        <作者>曹雪芹</作者>  
    </红楼梦>  
</四大名著>


 

11、XSD、XSLT、DOM4J解析XML

xml文件 000.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="000.xsl"?>
<addresses>
 <value>
 <no>A100</no>
 <addr>上单位dd</addr>
 </value>
 <value>
  <no>A101</no>
  <addr>ss撒发达</addr>
 </value>
</addresses>

xsd文件 000.xsd

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xs:element name="addresses">
  <xs:complexType>
   <xs:sequence>
    <xs:element name="value" maxOccurs="unbounded">
     <xs:complexType>
      <xs:sequence>
       <xs:element name="no" type="xs:string" />
       <xs:element name="addr" type="addr" />
      </xs:sequence>
     </xs:complexType>
    </xs:element>
   </xs:sequence>
  </xs:complexType>
 </xs:element>
 
 <xs:simpleType name="addr">
  <xs:restriction base="xs:string">
   <xs:minLength value="1" />
   <xs:maxLength value="5" />
  </xs:restriction>
 </xs:simpleType>
</xs:schema>

xslt文件 000.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <!-- XSLT 语法参考w3cschool -->
 <xsl:template match="/">
  <html>
   <head>
    <title>First XSLT example</title>
   </head>
   <body>
    <p>
     <table border='1'>
      <xsl:for-each select="addresses/value">
       <tr>
        <td>
         <xsl:value-of select="no" />
        </td>
        <td>
         <xsl:value-of select="addr" />
        </td>
       </tr>
      </xsl:for-each>
     </table>
    </p>
   </body>
  </html>
 </xsl:template>
</xsl:stylesheet>

bean文件 XmlBean.java

package com.zht.bean;
public class XmlBean {
    private String no;   
    private String addr;   
    public String getNo() {   
        return no;   
    }   
    public void setNo(String no) {   
        this.no = no;   
    }   
    public String getAddr() {   
        return addr;   
    }   
    public void setAddr(String addr) {   
        this.addr = addr;   
    }   
    @Override  
    public String toString() {   
        return "编号:" + this.no + ",地址:" + this.addr;   
    }   
}


路径文件 ReadXmlFileStream.java

package com.zht.xml;
import java.io.InputStream;
public class ReadXmlFileStream {
  private static final String XML_FILE = "com/zht/bean/000.xml";  
  private static final String XSD_FILE = "com/zht/bean/000.xsd";  
  private static final String XSL_FILE = "com/zht/bean/000.xsl";    
  private static final String HTML_FILE = "com/zht/bean/001.HTML";
     public static InputStream getXmlFileStream() {    
         return Thread.currentThread().getContextClassLoader()    
                 .getResourceAsStream(XML_FILE);    
     }
  public static String getXML_FILE() {
   return XML_FILE;
  }
  public static String getXSD_FILE() {
   return XSD_FILE;
  }
  public static String getXSL_FILE() {
   return XSL_FILE;
  }
  public static String getHTML_FILE() {
   return HTML_FILE;
  }    
}


解析xml文件 DOM4JParseXml.java

package com.zht.xml;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Iterator;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.SAXValidator;
import org.dom4j.io.XMLWriter;
import org.dom4j.util.XMLErrorHandler;
import com.zht.bean.XmlBean;
public class DOM4JParseXml {
  private static XmlBean address = new XmlBean();    
     public static void main(String[] args) {   
//     读取XML文件内容
//      ---====================读xml文件========================================
         long starttime = System.currentTimeMillis();    
         try {    
             InputStream in = ReadXmlFileStream.getXmlFileStream();    
             Reader reader = new InputStreamReader(in, "utf-8"); // 注意编码问题      
             SAXReader SaxReader = new SAXReader();    
             Document doc = SaxReader.read(reader);    
             Element root = doc.getRootElement();    
             Element childNode = null;    
//           枚举名称为value的节点    
             for (Iterator<Element> it = root.elementIterator("value"); it.hasNext();) {    
                 childNode = (Element) it.next();    
                 address.setNo(childNode.elementText("no"));    
                 address.setAddr(childNode.elementText("addr"));    
                 System.out.println(address);    
             }    
         } catch (Exception e) {    
             e.printStackTrace();    
         }    
         System.out.println("运行时间:" + (System.currentTimeMillis() - starttime) + " 毫秒");    
//    ---============================================================       
//     写XML文件内容
         try {
    testWrite();
   } catch (Exception e) {
    e.printStackTrace();
   }    
//      XML经XSD文件进行校验
         validateXMLByXSD();
            
//      XML经XSLT转换为HTML文件
      String xml = ReadXmlFileStream.getXML_FILE();
      String xsl = ReadXmlFileStream.getXSL_FILE();
      String out = ReadXmlFileStream.getHTML_FILE();
      xsl(xml,out,xsl);
     }      
     /**   
      * 写XML   
      */  
     public static void testWrite() throws Exception{  
         Document document = DocumentHelper.createDocument();
         Element root = document.addElement("root");
         Element element1 = root.addElement("user")
         .addAttribute("name","Alexander")
         .addAttribute("blog", "http://netnova.blogjava.net")
         .addText("我是中文的名字");
         XMLWriter writer = new XMLWriter(new FileOutputStream("com/zht/bean/001.xml"));
         writer.write(document);
         writer.close();    
         System.out.println("写XML文件成功~!");
     }
     /**   
      * 通过XSD(XML Schema)校验XML   
      */  
     public static void validateXMLByXSD() {   
         String xmlFileName = ReadXmlFileStream.getXML_FILE();   
         String xsdFileName = ReadXmlFileStream.getXSD_FILE();   
         try {   
             //创建默认的XML错误处理器    
             XMLErrorHandler errorHandler = new XMLErrorHandler();   
             //获取基于 SAX 的解析器的实例    
             SAXParserFactory factory = SAXParserFactory.newInstance();   
             //解析器在解析时验证 XML 内容。    
             factory.setValidating(true);   
             //指定由此代码生成的解析器将提供对 XML 名称空间的支持。    
//             factory.setNamespaceAware(true);   
             //使用当前配置的工厂参数创建 SAXParser 的一个新实例。    
             SAXParser parser = factory.newSAXParser();   
             //创建一个读取工具    
             SAXReader xmlReader = new SAXReader();   
             //获取要校验xml文档实例    
             Document xmlDocument = (Document) xmlReader.read(new File(xmlFileName));   
             //设置 XMLReader 的基础实现中的特定属性。核心功能和属性列表可以在 [url]http://sax.sourceforge.net/?selected=get-set[/url] 中找到。    
             parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");   
        parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", "file:" + xsdFileName);   
             //创建一个SAXValidator校验工具,并设置校验工具的属性    
             SAXValidator validator = new SAXValidator(parser.getXMLReader());   
             //设置校验工具的错误处理器,当发生错误时,可以从处理器对象中得到错误信息。    
             validator.setErrorHandler(errorHandler);   
             //校验    
             validator.validate(xmlDocument);
             XMLWriter writer = new XMLWriter(OutputFormat.createPrettyPrint());   
             //如果错误信息不为空,说明校验失败,打印错误信息    
             if (errorHandler.getErrors().hasContent()) {   
                 System.out.println("XML文件通过XSD文件校验失败!");   
                 writer.write(errorHandler.getErrors());   
                 System.out.println(errorHandler.getErrors().asXML());
             } else {   
                 System.out.println("Good! XML文件通过XSD文件校验成功!");   
             }   
         } catch (Exception ex) {   
             System.out.println("XML文件: " + xmlFileName + " 通过XSD文件:" + xsdFileName + "检验失败。\n原因: " + ex.getMessage());   
             ex.printStackTrace();   
         }   
     }
     /**   
      * 通过XSL生成HTML文件
      */  
     public static void xsl(String inFilename, String outFilename,
   String xslFilename) {
  try {
   TransformerFactory factory = TransformerFactory.newInstance();
   Templates template = factory.newTemplates(new StreamSource(
     new FileInputStream(xslFilename)));
   Transformer xformer = template.newTransformer();
   Source source = new StreamSource(new FileInputStream(inFilename));
   Result result = new StreamResult(new FileOutputStream(outFilename));
   xformer.transform(source, result);
   System.out.println("生成html成功~!");
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}


 类似资料: