zoukankan      html  css  js  c++  java
  • 无废话XML--DOM4J

    Dom4j  是一个易用的、开源的库,用于 XML ,XPath  和 XSLT 。它应用于 Java  平台,采用了 Java  集合框架并完全支持 DOM ,SAX 和 和 JAXP 。我们可以很方便的使用DOM4J来对一个XML进行CRUD操作,当然也可以面向对象编程,将一个XML里面的数据来转换成相关对象使用。
    • 常用有4个接口,4个工具类:
    Node  Node:为所有的 dom4j 中 XML 节点定义了多态行为
    Element  Element:定义 XML 元素
    Attribute  Attribute:定义了 XML 的属性
    Text  Text:定义 XML 文本节点。
    SAXReader:sax解析工具类
    DOMReader:dom解析工具类
    XMLWriter:写入XML文档工具类
    OutputFormat:输入格式化工具类。
    • 值得注意的2点是:
    1,格式化输出和指定编码。默认的输出方式为紧凑方式,默认编码为 UTF-8,但对于我们的应用而言,一般都要用到中文,并且希望显示时按自动缩进的方式的显示,这就需用到OutputFormat 类。

    2,Dom4j 编码问题。j ava中由W ri t er类继承下来的子类没有提供编码格式处理,所以dom 4j 也就无法对输出的文件进行正确的格式处理。这时候所保存的文件会以系统的默认编码对文件进行保存,在中文版的wi ndow下j ava的默认的编码为G BK,也就是所虽然我们标识了要将xm l 保存为ut f -8格式但实际上文件是以G BK格式来保存的,所以这也就是为什么能够我们使用G BK、G B2312编码来生成xm l 文件能正确的被解析,而以U TF-8格式生成的文件不能被xm l 解析器所解析的原因。所以在创建XMLWriter这个对象时,最好使用FileOutputStream,不要用FileWriter。


    以下代码使用了DOM4J对XML实现了CRUD操作:

    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.net.URL;
    import java.util.List;
    
    import org.dom4j.Attribute;
    import org.dom4j.Comment;
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.DocumentHelper;
    import org.dom4j.Element;
    import org.dom4j.Node;
    import org.dom4j.Text;
    import org.dom4j.io.OutputFormat;
    import org.dom4j.io.SAXReader;
    import org.dom4j.io.XMLWriter;
    
    /**
     * 
     * @version 1L
     * @author LinkinPark
     * @since 2014-12-29
     * @motto 梦似烟花心似水,同学少年不言情
     * @desc ^其实DOM4J还是比较简单的,API也不是很多,着重记住Document,Element,Attribute就好了。
     *       Node是上面所有的接口的公共一个多态接口
     */
    public class Dom4jHandler
    {
    	public Document parse(URL url) throws DocumentException
    	{
    		SAXReader reader = new SAXReader();
    		Document document = reader.read(url);
    		return document;
    	}
    
    	//解析XML
    	public void read(String fileName) throws DocumentException
    	{
    		SAXReader reader = new SAXReader();
    		//定义XML文档
    		Document document = reader.read(this.getClass().getResourceAsStream("/" + fileName));
    		//定义XML元素
    		Element rootElement = document.getRootElement();
    		System.out.println("根节点是:" + rootElement.getName());
    		List<Element> childElements = rootElement.elements();
    		for (Element element : childElements)
    		{
    			System.out.println(element.getName());
    			//下面这个nodeCount里面包含了所有的节点,那个换行也包含上了呢
    			System.out.println(element.nodeCount());
    			for (int i = 0; i < element.nodeCount(); i++)
    			{
    				Node node = element.node(i);
    				System.out.println("节点的名字是" + node.getName() + ";节点的值是" + node.getText() + ";节点的类型是" + node.getNodeTypeName());
    				if (node instanceof Element)
    				{
    					System.out.println("这里是元素!");
    				}
    				else if (node instanceof Comment)
    				{
    					System.out.println("这里是注释!");
    				}
    				else
    				{
    					System.out.println("这里鸡毛都没有!");
    				}
    			}
    			//现在开始解决上面那个空白的换行问题 如何去掉呢?
    			System.out.println("========开始去掉那个空白============");
    			for (int i = 0; i < element.nodeCount(); i++)
    			{
    				Node node = element.node(i);
    				if (node instanceof Text)
    				{
    					System.out.println("这里是文本!");
    					if ("".equals(node.getText().trim()))
    					{
    						System.out.println("这里就是要去掉的空白吆。。。");
    					}
    					else
    					{
    						System.out.println("这里是内容不是空白,所以不要去掉。。。");
    						System.out.println(node.getText().trim());
    					}
    				}
    			}
    			System.out.println("=========去掉空白结束=============");
    			List<Attribute> attributes = element.attributes();
    			//遍历这个元素里面的所有的属性
    			for (Attribute attribute : attributes)
    			{
    				System.out.println(attribute.getName() + ":" + attribute.getValue());
    			}
    			//现在我只想得到version这个属性
    			Attribute attribute = element.attribute("version");
    			System.out.println(attribute.getName() + ":" + attribute.getValue());
    			//现在我只想直接拿出version这个属性的值
    			String attributeValue = element.attributeValue("version");
    			System.out.println(attributeValue);
    			//获得element这个元素里面的所有的子节点
    			List<Element> childs = element.elements();
    			for (Element element2 : childs)
    			{
    				//Element元素里面没有getValue方法,Attribute里面有,其实和getText是一样的
    				System.out.println(element2.getName() + ":" + element2.getText());
    			}
    			//同样的Element也可以直接获得值,而且还可以去除空格
    			System.out.println(element.elementText("driver"));
    			System.out.println(element.elementTextTrim("driver"));
    		}
    	}
    
    	//写出一个XML
    	public void write(String fileName) throws Exception
    	{
    		//生成一个XML文档
    		Document document = DocumentHelper.createDocument();
    		//给XML文档也就是Document添加数据
    		Element root = document.addElement("DataSource");//添加根节点
    		root.addComment("这里是LinkinPark自己生成的XML。。。");//添加注释
    		Element dateBase = root.addElement("database");//在root根节点下添加一个子节点
    		dateBase.addAttribute("name", "mysql");//给dateBase添加属性
    		dateBase.addAttribute("version", "5.0");//给dateBase添加属性
    		dateBase.addElement("driver").setText("com.mysql.jdbc.Driver");//给dateBase添加子节点
    		dateBase.addElement("url").setText("jdbc:mysql://localhost:3306/linkinjdbc");//给dateBase添加子节点
    		dateBase.addElement("user").setText("root");//给dateBase添加子节点
    		dateBase.addElement("password").setText("root");//给dateBase添加子节点
    		//将这个XML文档写出到文件去
    		writerTo(document, fileName);
    	}
    
    	//专门定义一个写出XML到指定文件的方法
    	public void writerTo(Document document, String fileName) throws Exception
    	{
    		//OutputFormat of = OutputFormat.createCompactFormat();//这个format是不换行的,没有格式化过的
    		OutputFormat of = OutputFormat.createPrettyPrint();//这里是格式化过的
    		of.setEncoding("UTF-8");
    		//XMLWriter writer = new XMLWriter(new FileWriter(fileName), of);
    		//最好使用下面这种情况,这样子可以有效的解决XML编码是UTF-8的编码错误问题
    		XMLWriter writer = new XMLWriter(new FileOutputStream(fileName), of);
    		writer.write(document);
    		writer.close();
    	}
    
    	//修改一个XML 2个参数:一个是读取文件自己的位置,一个是要保存到的文件的位置。
    	//这里也很好的说明了加载文件和流的区别:使用类加载器是直接从内存中要的,所以相对路径没有src;但是要是使用一个流来指定输入位置,那么就是文件系统,src要有的。
    	public void update(String fileName1, String fileName2) throws Exception
    	{
    		//现在我要修改LinkinPark下面的数据库的名称和数据库连接的名称,一个是属性,一个是节点
    		SAXReader reader = new SAXReader();
    		Document document = reader.read(this.getClass().getResourceAsStream("/" + fileName1));
    		Element rootElement = document.getRootElement();
    		List<Element> childElements = rootElement.elements("database");
    		for (Element element : childElements)
    		{
    			if ("mysql".equals(element.attributeValue("name")))
    			{
    				//换了这个属性的名字
    				element.attribute("name").setText("Oracle1");
    			}
    			List<Element> childs = element.elements("driver");
    			for (Element element2 : childs)
    			{
    				System.out.println(element2.getText().trim());
    				if ("com.mysql.jdbc.Driver".equals(element2.getText().trim()))
    				{
    					element2.setText("oracle.jdbc.driver.OracleDriver");
    				}
    			}
    		}
    		writerTo(document, fileName2);
    	}
    
    	//删除一个XML里面的一部分内容
    	public void delete(String fileName1, String fileName2) throws Exception
    	{
    		//现在我要删除LinkinPark下面的数据库的名称和数据库连接的名称,一个是属性,一个是节点
    		SAXReader reader = new SAXReader();
    		Document document = reader.read(this.getClass().getResourceAsStream("/" + fileName1));
    		Element rootElement = document.getRootElement();
    		List<Element> childElements = rootElement.elements("database");
    		for (Element element : childElements)
    		{
    			//删除掉这个属性
    			element.remove(element.attribute("name"));
    			//删除掉这个子节点
    			element.remove(element.element("driver"));
    		}
    		writerTo(document, fileName2);
    	}
    
    	public static void main(String[] args) throws Exception
    	{
    		//new Dom4jHandler().read("data-sources.xml");
    		new Dom4jHandler().write("src/LinkinPark...");
    		//new Dom4jHandler().update("LinkinPark...", "src/LinkinPark...");
    		//new Dom4jHandler().delete("LinkinPark...", "src/LinkinPark...");
    	}
    
    }
    

    <?xml version="1.0" encoding="UTF-8"?>
    
    <DataSource>
      <!--这里是LinkinPark自己生成的XML。。。-->
      <database name="mysql" version="5.0">
        <driver>com.mysql.jdbc.Driver</driver>
        <url>jdbc:mysql://localhost:3306/linkinjdbc</url>
        <user>root</user>
        <password>root</password>
      </database>
    </DataSource>
    


  • 相关阅读:
    Java实现旅行商问题
    Java实现旅行商问题
    Java实现旅行商问题
    Java实现旅行商问题
    递归执行顺序的探究
    递归执行顺序的探究
    递归执行顺序的探究
    配置我的Ubuntu Server记(包括桌面及VNC,SSH,NTP,NFS服务) good
    罗辑思维 137 藩镇割据:毒药还是良药?(要懂得自我收敛?不要什么事情都自己做?)
    云计算CTO工作的具体内容(挺详细)
  • 原文地址:https://www.cnblogs.com/LinkinPark/p/5233110.html
Copyright © 2011-2022 走看看