dom4j处理带命名空间的XML-使用XPath(转)

XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。

XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。

w3school XPath教程

Dom4J学习笔记

 

例子1:

Xml代码  收藏代码
  1. <report  xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.15" id="1">  
  2.     <list-property name="cssStyleSheets">  
  3.         <structure>  
  4.             <property name="fileName">D: eport.css</property>  
  5.         </structure>  
  6.     </list-property>  
  7. </report>  

 

第一个方案.设置你的xpath的命名空间setNamespaceURIs

    XPath x = document.createXPath("//design:list-property");

    x.setNamespaceURIs(map);

    x.selectNodes(document);

 

Java代码  收藏代码
  1. public class TransferXML {  
  2.     public static void main(String[] args) throws Exception{          
  3.         SAXReader saxReader = new SAXReader();  
  4.         File file = new File("D:\test.xml");  
  5.         Document document = saxReader.read(file);  
  6.   
  7.         Map map = new HashMap();  
  8.         map.put("design","http://www.eclipse.org/birt/2005/design");  
  9.         XPath x = document.createXPath("//design:list-property");  
  10.         x.setNamespaceURIs(map);  
  11.         List nodelist = x.selectNodes(document);  
  12.         System.out.println(nodelist.size());  
  13.     }  
  14. }  

 

 第二个解决方案:设置你的DocumentFactory()的命名空间 setXPathNamespaceURIs

    saxReader.getDocumentFactory().setXPathNamespaceURIs(map);

    Document document = saxReader.read(file);

    document.selectNodes("//design:list-property");

 

Java代码  收藏代码
  1. public class TransferXML {  
  2.     public static void main(String[] args) throws Exception{  
  3.         Map map = new HashMap();  
  4.         map.put("design","http://www.eclipse.org/birt/2005/design");  
  5.         SAXReader saxReader = new SAXReader();  
  6.         File file = new File("D:\test.xml");  
  7.         saxReader.getDocumentFactory().setXPathNamespaceURIs(map);  
  8.         Document document = saxReader.read(file);  
  9.         List tmp = document.selectNodes("//design:list-property");  
  10.         System.out.println(tmp.size());  
  11.     }  
  12. }  

 

第三种方法:就是不使用开发环境给你提供的一系列对象,而是用XPath语法中自带的local-name() 和 namespace-uri() 指定你要使用的节点名和命名空间

当你遇到使用xslt来样式化xml时,就知道这个笨方法的好处了:

    Document document =  saxReader.read(file);

    List tmp = document.selectNodes("//*[local-name()='report' and namespace-uri()='http://www.eclipse.org/birt/2005/design']/* [local-name()='list-property']");

 

Java代码  收藏代码
  1. public class TransferXML {  
  2.     public static void main(String[] args) throws Exception  
  3.         SAXReader saxReader = new SAXReader();  
  4.         File file = new File("D:\test.xml");  
  5.         Document document = saxReader.read(file);  
  6.         List tmp = document.selectNodes("//*[local-name()='report' and namespace-uri()='http://www.eclipse.org/birt/2005/design']/* [local-name()='list-property']");  
  7.         System.out.println(tmp.size());  
  8.     }  
  9. }  

 

例子2:

 

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>    
  2.     
  3. <addresses  xmlns="http://www.example.org/cameraServerAddress" >    
  4.         
  5.     <address>    
  6.         <db>r1app.nvts.co</db>    
  7.         <zh>美国东1</zh>    
  8.         <en>US-East1</en>    
  9.     </address>    
  10.     <address>        
  11.         <db>r2app.nvts.co</db>    
  12.         <zh>日本1</zh>        
  13.         <en>JP-1</en>    
  14.     </address>    
  15.         
  16.     <address>    
  17.         <db>r3app.nvts.co</db>    
  18.         <zh>欧洲1</zh>    
  19.         <en>EU-1</en>    
  20.     </address>          
  21. </addresses>    

 

Java代码  收藏代码
  1. /**  
  2.      * 初始化CameraServerAddress,从xml配置文件初始化  
  3.      */    
  4.     @SuppressWarnings("unchecked")    
  5.     public void initCameraServerAddresses(){    
  6.         try {    
  7.             Map<String,String> uris = new HashMap<String, String>();    
  8.             uris.put("cameraServerAddress"  , "http://www.example.org/cameraServerAddress");    
  9.             SAXReader reader = new SAXReader();     
  10.             Document root = reader.read(this.getClass().getClassLoader().getResourceAsStream("cameraServerAddresses.xml"));    
  11.             XPath xpath = root.createXPath("//cameraServerAddress:address");    //创建XPath    
  12.             xpath.setNamespaceURIs(uris);   //加入NameSpace    
  13.             List<DefaultElement> nodes = xpath.selectNodes(root); //执行搜索    
  14.             for (DefaultElement de : nodes) {    
  15.                    de.add(new Namespace("cameraServerAddress", "http://www.example.org/cameraServerAddress"));  //这里也要再次加入NameSpace    
  16.                    Node db = de.selectSingleNode("cameraServerAddress:db");    
  17.                    Node zh =  de.selectSingleNode("cameraServerAddress:zh");    
  18.                    Node en = de.selectSingleNode("cameraServerAddress:en");    
  19.                    NVContext.cameraServerAddresses.add(new CameraServerAddress(    
  20.                            db.getText(), zh.getText(), en.getText()));      
  21.             }    
  22.                 
  23.         } catch (Exception e) {    
  24.             log.error("初始化CameraServerAddress失败");      
  25.             e.printStackTrace();    
  26.         }    
  27.             
  28.     }    

 

例子3(自己例子):

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <webservices xmlns="http://ws.test.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="webservices.xsd">    
  4.   <webservice wsname="ws1" wsversion="">   
  5.     <wsdlurl>http://localhost:8888/ws1?wsdl</wsdlurl>   
  6.   </webservice>    
  7.   <webservice wsname="ws2">   
  8.     <wsdlurl>http://localhost:8888/ws2?wsdl</wsdlurl>   
  9.   </webservice>    
  10.   <webservice wsname="ws3" wsversion="v1">   
  11.     <wsdlurl>http://localhost:8888/ws3?wsdl</wsdlurl>   
  12.   </webservice>    
  13.   <webservice wsname="srv4">   
  14.     <wsdlurl>http://localhost:8889/ws4?wsdl</wsdlurl>   
  15.   </webservice>    
  16.   <webservice wsname="ESB_YS_YS_InquiryMachineInfoSrv">  
  17.     <wsdlurl>http://10.204.104.87:8888/ESB_YS_YS_InquiryMachineInfoSrv/ESBYSYSInquiryMachineInfoSrv?wsdl</wsdlurl>  
  18.   </webservice>  
  19. </webservices>  

  

Java代码  收藏代码
  1. /** 
  2.      * 添加或更新单个webservice子节点 
  3.      * @param wi 封装的服务信息 
  4.      */  
  5.     public synchronized void addOrUpdate(WebserviceNode wi) {  
  6.         if(doc != null){  
  7.             Element root = doc.getRootElement();  
  8.               
  9.             addOrUpdateWebservice(wi, root);  
  10.               
  11.             save();  
  12.         }  
  13.     }  

 

 

Java代码  收藏代码
  1. /** 
  2.      * 在指定的节点上添加webservice子节点 
  3.      *  
  4.      * @param wi 封装的服务信息 
  5.      * @param root root节点 
  6.      */  
  7.     private void addOrUpdateWebservice(WebserviceNode wi, Element root) {  
  8.         removeWebservices(wi, root);  
  9.           
  10.         addOrUpdateWebserviceElement(wi, root);  
  11.           
  12.         wis.add(wi);  
  13.     }  

 

Java代码  收藏代码
  1. private void removeWebservices(WebserviceNode wi, Element root) {  
  2.         List<Element> es = findWebserviceElements(wi, root);  
  3.           
  4.         if(es.size() > 0){  
  5.             // 删除doc中的元素  
  6.             for(Element e : es){  
  7.                 root.remove(e);  
  8.             }  
  9.             // 删除集合中的元素  
  10.             Iterator<WebserviceNode> wiIterator = wis.iterator();  
  11.             while(wiIterator.hasNext()){    
  12.                 WebserviceNode i = wiIterator.next();    
  13.                 if(i.equals(wi)){  
  14.                     wiIterator.remove();  
  15.                 }  
  16.             }    
  17.         }  
  18.     }  

 

查找满足条件的子节点:

Java代码  收藏代码
  1. /** 
  2.      * 查找匹配的webservice元素 
  3.      *  
  4.      * @param wi 
  5.      * @param root 
  6.      * @return 
  7.      */  
  8.     @SuppressWarnings("unchecked")  
  9.     private List<Element> findWebserviceElements(WebserviceNode wi, Element root) {  
  10.         Map<String, String> ns = new HashMap<String, String>();  
  11.         ns.put("vis", "http://ws.test.com");  
  12.           
  13.         String xpath = "/vis:webservices/vis:webservice[@wsname='"+ wi.getWsName() + "'" + (wi.hasVersionInfo() ? " and @wsversion='" + wi.getWsVersion() + "'" : " and (not(@wsversion) or normalize-space(@wsversion)='')") + "]";  
  14.         XPath x = root.createXPath(xpath);  
  15.         x.setNamespaceURIs(ns);  
  16.           
  17.         //System.out.println(xpath);  
  18.           
  19.         List<Element> es = x.selectNodes(root);  
  20.         return es;  
  21.     }  

 

Java代码  收藏代码
  1. /** 
  2.      * 在指定的节点上添加webservice子节点(xml document) 
  3.      *  
  4.      * @param wi 
  5.      * @param root 
  6.      */  
  7.     private void addOrUpdateWebserviceElement(WebserviceNode wi, Element root) {  
  8.         Element ws = root.addElement("webservice");  
  9.         ws.addAttribute("wsname", wi.getWsName());  
  10.         if(wi.hasVersionInfo()){  
  11.             ws.addAttribute("wsversion", wi.getWsVersion());  
  12.         }  
  13.         ws.addElement("wsdlurl").setText(wi.getWsdlUrl());  
  14.     }  

 保存XML文件:

Java代码  收藏代码
  1. /** 
  2.      * 保存至硬盘 
  3.      */  
  4.     private void save() {  
  5.         // 将document保存至硬盘  
  6.         OutputFormat format = OutputFormat.createPrettyPrint();  
  7.         try {  
  8.             XMLWriter writer = new XMLWriter(new FileWriter(PATH), format);  
  9.             writer.write(doc);  
  10.             writer.close();  
  11.         } catch (IOException e) {  
  12.             System.err.println("Persist '" + PATH + "' is Failed...");  
  13.             e.printStackTrace();  
  14.         }  
  15.     }  

posted on 2016-06-22 08:03  World_maker  阅读(4831)  评论(0编辑  收藏  举报

导航