dom4j處理帶命名空間的XML-使用XPath(轉)

XPath 是一門在 XML 文檔中查找信息的語言。XPath 可用來在 XML 文檔中對元素和屬性進行遍歷。css

XPath 使用路徑表達式來選取 XML 文檔中的節點或節點集。節點是經過沿着路徑 (path) 或者步 (steps) 來選取的。node

w3school XPath教程web

Dom4J學習筆記app

 

例子1:dom

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的命名空間setNamespaceURIseclipse

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

    x.setNamespaceURIs(map);ui

    x.selectNodes(document);this

 

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()的命名空間 setXPathNamespaceURIsurl

    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.     }  
相關文章
相關標籤/搜索