zoukankan      html  css  js  c++  java
  • javaXML

    XML不再多说,XML 约束也不用说了,这里讲讲java如何对XML操作。

    java中使用XML,目前常用的就是Jaxp(sun)和dom4j了,这里先讲讲java自带的Jaxp包

    JAXP 开发包是J2SE的一部分,它由javax.xml、org.w3c.dom 、org.xml.sax 包及其子包组成

    Jaxp的xml解析器有两种,一种是DOM解析器,一种是SAX解析器,两种各自应用在不同的场景上。

    在DOM解析时,会把xml中各个节点视为对象,然后根据父子关系相互嵌套。优点时容易操纵,缺点也很明显,必须全部通读xml并加载进内存。

    DOM解析的流程:

    1,DocumentBuilderFactory是抽象类,newInstance()方法会根据本地平台安装的xml解析器自动创建相应的工厂实力

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    

    2,DocumentBuilder的newDocumentBuilder()方法会得到本地xml解析器相应的DocumentBuilder实力

    DocumentBuilder documentB = dbf.newDocumentBuilder();
    

    3,解析xml,根据DocumentBuilder的parse方法。

    Document document = documentB.parse(new File(path));
    
    //看文档可以知道,parse可以从解析File、InputSource(经过包装的InputStream)、InputStream和URI字符串

    4,Document代表了整个XML文档,首先获取根节点,Element就是标签,它们都属于Node,也就是说,都实现了Node接口

    Element root=document.getDocumentElement();

    5,下面就是增删改查了

    增加结点

    //增加一个结点,注意,增加节点是对document操作,Document实现了这个方法
    Element newStudent=document.createElement("student");
    			
    //增加一个属性,属性也算是结点,一切都是Node
    Attr cid=document.createAttribute("idcard");
    //给属性设置值
    cid.setValue("1121");
    			
    //将属性添加进这个标签
    newStudent.setAttributeNode(cid);
    			
    //最后,将这个结点添加进根节点,注意,是对根节点添加,不是Document
    root.appendChild(newStudent);
    

    提取某节点信息(查)

    //首先根据第3步,已经获得根结点,也就是Element root
    
    
    //获取所有标签名为sutdent的节点集合
    NodeList students=root.getElementsByTagName("student");
    
    //至于获取标签属性以及text内容,自行看手册
    
    //要注意的是,换行和制表符'\n\t'这些,也会被当做text内容解析
    //至于xml的编码问题,都是自动的,不用手动设置了。
    

    更改结点内容(很多都是Node接口的方法,自行查看手册即可)

    //设置标签内容
    Node.setTextContent(String text)
    
    //设置属性内容
    Attr.setValue(String value)
    

    删除结点

    Node.removeChild(Node node)
    

    6,操作完xml,保存结果

    javax.xml.transform包中的Transformer类用于把代表XML文件的Document对象转换为某种格式后进行输出,例如把xml文件应用样式表后转成一个html文档。
    利用这个对象,当然也可以把Document对象又重新写入到一个XML文件中。
    //1、获得Transformer工厂
    TransformerFactory tff=TransformerFactory.newInstance();
    
    //2、对于DOM对象,使用树来表示,肯定是个多叉树了,,,
    //这个类,就是将树,变为结果树
    Transformer tf = tff.newTransformer();
    
    //3、把document(DOM)转换为xml source
    Source sc=new DOMSource(document);
    
    //4、创建一个DOM目标,这里是个流
    Result rs=new StreamResult(new File(path_URI));
    
    //5、将 XML Source 转换为 Result,这样就写入数据流了
    tf.transform(sc, rs);

    DOM解析就到这里,如果以网络流读取一个大的xml文件的话,这样肯定是不行的,不可能一直等到它全部读完载入内存再操作吧。。。。。光读取的话,就用SAX了。

    SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器:
    •解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。
    •解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。

    事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理

    我们常用的就是ContentHandler了。

    下面是sax示例

    //定义工厂api,用以配置和获取sax解析器
    		SAXParserFactory spf = SAXParserFactory.newInstance();
    		
    		//得到解析器对象
    		SAXParser sp = spf.newSAXParser();
    		
    		//得到一个xmlreader读取器
    		XMLReader xmlReader = sp.getXMLReader();
    
    		//注册一个内容事件处理器 ContentHandler,一般情况下,使用ContentHandler接口的已知
    		//子类DefaultHandler就行了
    		
    		xmlReader.setContentHandler(new DefaultHandler(){
    			//为了方便,以内部类重写需要使用到的方法
    			
    			//开始读取标签
    			public void startElement(String uri, //命名空间
                        String localName, //标签名
                        String qName, //限定名称
                        Attributes attributes //属性
                        ){
    				
    				///////////////////////////
    				//获取标签的个数
    				attr.getLength();
    				//其它的看手册				
    			}
    			
    			//开始读取文档
    			public void startDocument(){
    				
    			}
    			
    			//读取到标签尾
    			public void endElement( String namespaceURI,
    		              String localName,
    		              String qName ) {
    
    		   }
    			
    			//读取标签体,注意的是,sax是分段读取的,每次最大读取是2kb
    			public void characters(char[] ch,
                        int start,
                        int length
                       ){
    				//读取大数据的时候注意sax是分段读取的,每次最大读取是2kb
    				
    				
    			}
               
    
    			
    		});
    		
    		
    		//开始读取xml数据
    		xmlReader.parse("book.xml");
    

    到这里,我们发现SAX虽然比DOM效率高,但是它是顺序读取的,无法回头,且只能从头到尾。

    现在就可以使用Dom4j了,它是第三方包

    Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。
    Dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j。
    使用Dom4j开发,需下载dom4j相应的jar文件。

    lDOM4j中,获得Document对象的方式有三种:
    //1.读取XML文件,获得document对象            
              SAXReader reader = new SAXReader();
              Document   document = reader.read(new File("input.xml"));
    
    //2.解析XML形式的文本,得到document对象.
              String text = "<members></members>";  
              Document document = DocumentHelper.parseText(text);
    //3.主动创建document对象.
              Document document = DocumentHelper.createDocument();             //创建根节点
              Element root = document.addElement("members");
    

    dom4j 中结点对象的操作:

      //1.获取文档的根节点.
    	Element root = document.getRootElement();
    	
      //2.取得某个节点的子节点.
    	Element element=node.element(“书名");
    	
      //3.取得节点的文字
    	String text=node.getText();
      //4.取得某节点下所有名为“member”的子节点,并进行遍历.
    	List nodes = rootElm.elements("member");
    	for (Iterator it = nodes.iterator(); it.hasNext();) {
    		Element elm = (Element) it.next();
    		// do something
    	}
    	
      //5.对某节点下的所有子节点进行遍历.
    	for(Iterator it=root.elementIterator();it.hasNext();){
    		Element element = (Element) it.next();
     		// do something
    	}
    	
      //6.在某节点下添加子节点.
    	Element ageElm = newMemberElm.addElement("age");
    	
      //7.设置节点文字.
    	element.setText("29");
    	
      //8.删除某节点.
    	//childElm是待删除的节点,parentElm是其父节点
    	parentElm.remove(childElm);
      //9.添加一个CDATA节点.
    	Element contentElm = infoElm.addElement("content");
    	contentElm.addCDATA(diary.getContent());
    

    对节点对象属性的操作:

      //1.取得某节点下的某属性
    	Element root=document.getRootElement();
    	//属性名name
        Attribute attribute=root.attribute("size");
    
      //2.取得属性的文字
     	String text=attribute.getText();
    
      //3.删除某属性
    	Attribute attribute=root.attribute("size");
    	root.remove(attribute);
    	
      //4.遍历某节点的所有属性
    	Element root=document.getRootElement(); 
    	for(Iterator it=root.attributeIterator();it.hasNext();){
    		Attribute attribute = (Attribute) it.next();
    		String text=attribute.getText();
    		System.out.println(text);
    	}
      //5.设置某节点的属性和文字.
    	newMemberElm.addAttribute("name", "sitinspring");
    
      //6.设置属性的文字
    	Attribute attribute=root.attribute("name");
    	attribute.setText("sitinspring");
    

    在指定位置中插入元素:

    1.得到插入位置的节点列表(list)
    2.调用list.add(index,elemnent),由index决定element的插入位置。
    3.list中存储的是引用,对list进行了更改,既对document进行了更改
    //Element元素可以通过DocumentHelper对象得到。示例代码:
    
    Element aaa = DocumentHelper.createElement("aaa");
    aaa.setText("aaa");
    
    List list = root.element("书").elements();
    list.add(1, aaa);
    

    写入XML文档

      //1.文档中全为英文,不设置编码,直接写入的形式.
    	XMLWriter writer = new XMLWriter(new  FileWriter("output.xml"));
    	writer.write(document);
    	writer.close();
    
      //2.文档中含有中文,设置编码格式写入的形式.OutputFormat format = OutputFormat.createPrettyPrint();// 指定XML编码                   
    	format.setEncoding("GBK");
    	XMLWriter writer = new XMLWriter(newFileWriter("output.xml"),format);
    	writer.write(document);
    	writer.close();
    

    XML与字符串的转换

      //1.将字符串转化为XML 
    	String text = "<members> <member>sitinspring</member></members>";
    	Document document = DocumentHelper.parseText(text);
    
      //2.将文档或节点的XML转化为字符串.
    	SAXReader reader = new SAXReader();
    	Document   document = reader.read(new File("input.xml"));
    	Element root=document.getRootElement();    
    	String docXmlText=document.asXML();
    	String rootXmlText=root.asXML();
    	Element memberElm=root.element("member");
    	String memberXmlText=memberElm.asXML();
    

    在Dom4j中使用xpath查询路径

    xpath路径表达式就像正则表达式一样,可以免去自己写遍历对比代码了。

    //dom4j的包中的document..........
    List<Node> list = document.selectNodes("//xpath");
    

    上面的所有代码基本上算是模板代码了,用的时候多看手册,拷贝粘贴就ok了

  • 相关阅读:
    在Visual Studio 2019中配置OpenCV环境
    Java中的垃圾回收
    线程池
    Java中锁优化
    二叉树的几种遍历
    java中Comparator的用法(排序、分组)
    java8 stream
    Java后台生成二维码并上传到阿里云OSS
    代码生成器的成长过程
    软件的军工六性
  • 原文地址:https://www.cnblogs.com/hangxin1940/p/2067356.html
Copyright © 2011-2022 走看看