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

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

w3school XPath教程

Dom4J学习笔记

例子1:

  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);

  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. Map map = new HashMap();
  7. map.put("design","http://www.eclipse.org/birt/2005/design");
  8. XPath x = document.createXPath("//design:list-property");
  9. x.setNamespaceURIs(map);
  10. List nodelist = x.selectNodes(document);
  11. System.out.println(nodelist.size());
  12. }
  13. }

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

saxReader.getDocumentFactory().setXPathNamespaceURIs(map);

Document document = saxReader.read(file);

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

  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']");

  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:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <addresses  xmlns="http://www.example.org/cameraServerAddress" >
  3. <address>
  4. <db>r1app.nvts.co</db>
  5. <zh>美国东1</zh>
  6. <en>US-East1</en>
  7. </address>
  8. <address>
  9. <db>r2app.nvts.co</db>
  10. <zh>日本1</zh>
  11. <en>JP-1</en>
  12. </address>
  13. <address>
  14. <db>r3app.nvts.co</db>
  15. <zh>欧洲1</zh>
  16. <en>EU-1</en>
  17. </address>
  18. </addresses>
  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. } catch (Exception e) {
  23. log.error("初始化CameraServerAddress失败");
  24. e.printStackTrace();
  25. }
  26. }

例子3(自己例子):

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <webservices xmlns="http://ws.test.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="webservices.xsd">
  3. <webservice wsname="ws1" wsversion="">
  4. <wsdlurl>http://localhost:8888/ws1?wsdl</wsdlurl>
  5. </webservice>
  6. <webservice wsname="ws2">
  7. <wsdlurl>http://localhost:8888/ws2?wsdl</wsdlurl>
  8. </webservice>
  9. <webservice wsname="ws3" wsversion="v1">
  10. <wsdlurl>http://localhost:8888/ws3?wsdl</wsdlurl>
  11. </webservice>
  12. <webservice wsname="srv4">
  13. <wsdlurl>http://localhost:8889/ws4?wsdl</wsdlurl>
  14. </webservice>
  15. <webservice wsname="ESB_YS_YS_InquiryMachineInfoSrv">
  16. <wsdlurl>http://10.204.104.87:8888/ESB_YS_YS_InquiryMachineInfoSrv/ESBYSYSInquiryMachineInfoSrv?wsdl</wsdlurl>
  17. </webservice>
  18. </webservices>
  1. /**
  2. * 添加或更新单个webservice子节点
  3. * @param wi 封装的服务信息
  4. */
  5. public synchronized void addOrUpdate(WebserviceNode wi) {
  6. if(doc != null){
  7. Element root = doc.getRootElement();
  8. addOrUpdateWebservice(wi, root);
  9. save();
  10. }
  11. }
  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. addOrUpdateWebserviceElement(wi, root);
  10. wis.add(wi);
  11. }
  1. private void removeWebservices(WebserviceNode wi, Element root) {
  2. List<Element> es = findWebserviceElements(wi, root);
  3. if(es.size() > 0){
  4. // 删除doc中的元素
  5. for(Element e : es){
  6. root.remove(e);
  7. }
  8. // 删除集合中的元素
  9. Iterator<WebserviceNode> wiIterator = wis.iterator();
  10. while(wiIterator.hasNext()){
  11. WebserviceNode i = wiIterator.next();
  12. if(i.equals(wi)){
  13. wiIterator.remove();
  14. }
  15. }
  16. }
  17. }

查找满足条件的子节点:

  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. String xpath = "/vis:webservices/vis:webservice[@wsname='"+ wi.getWsName() + "'" + (wi.hasVersionInfo() ? " and @wsversion='" + wi.getWsVersion() + "'" : " and (not(@wsversion) or normalize-space(@wsversion)='')") + "]";
  13. XPath x = root.createXPath(xpath);
  14. x.setNamespaceURIs(ns);
  15. //System.out.println(xpath);
  16. List<Element> es = x.selectNodes(root);
  17. return es;
  18. }
  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文件:

  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. }

dom4j处理带命名空间的XML-使用XPath(转)的更多相关文章

  1. dom4j解析带命名空间的xml文件

    文件内容如下 <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=& ...

  2. 带命名空间的XML的dom4j应用<转>

    Element root = document.getRootElement();     List   recordenvlist = document.selectNodes("//gm ...

  3. C#读取带命名空间的xml,xaml文件的解决方案

    使用C#读取xml文件有三种常用的方式: 1.xmlDocument 2.XmlTextReader 3.Linq To Xml 但是这些方式在读写有些带命名空间的xml时就不知道怎么办了(例如把xa ...

  4. 由“Jasperrpeorts 4.1.2升级到5.1.2对flex项目的解析”到AS3 带命名空间的XML的操作

    原文同步至:http://www.waylau.com/from-jasperrpeorts-4-1-2-upgraded-to-5-1-2-parsing-of-flex-projects-to-t ...

  5. C#读取带命名空间的xml

    首先带有命名空间的xml读取可以使用Xml.Linq,也可以使用xpath,本文将采用xpath的方式解析. 原文参考了:https://www.cnblogs.com/duanjt/p/544054 ...

  6. Linq to xml 操作带命名空间的xml

    昨天需要操作用代码操作csproj文件,实现不同vs版本的切换. 在用XElement读取了csproj文件以后怎么也获取不到想要的对象. 反反复复试验了好多次都不得要领:先看下csproj文件的内容 ...

  7. XML记一次带命名空间的xml读取

    public static void ReadXML(string xmlUrl) { //判断文件是否存在 if (!File.Exists(xmlUrl)) { Console.WriteLine ...

  8. linq检索带命名空间的xml

    XElement el = XElement.Load(fil); XNamespace ns = "http://schemas.microsoft.com/ado/2009/11/edm ...

  9. Linq to Xml读取复杂xml(带命名空间)

    前言:xml的操作方式有多种,但要论使用频繁程度,博主用得最多的还是Linq to xml的方式,觉得它使用起来很方便,就用那么几个方法就能完成简单xml的读写.之前做的一个项目有一个很变态的需求:C ...

随机推荐

  1. 【学术篇】NOIP2017 d2t3 列队phalanx splay做法

    我可去他的吧.... ==============先胡扯些什么的分割线================== 一道NOIP题我调了一晚上...(其实是因为昨晚没有找到调试的好方法来的说...) 曾经我以 ...

  2. bzoj 3579: 破冰派对

    题意: 给你一个图,问你有多少个方案把他分成连个新的图.使得一个图是一个团,另外一个是独立集 一些闲话: 以前做过一次这个题..当时听说爆搜可以过,就无脑莽过去了.. 也没有思考为什么爆搜能过,或者有 ...

  3. zepto(mark)

    Zepto的设计目的是提供 jQuery 的类似的API,但并不是100%覆盖 jQuery .Zepto设计的目的是有一个5-10k的通用库.下载并快速执行.有一个熟悉通用的API,所以你能把你主要 ...

  4. tomcat的webapps下面包含五个自带的项目

    1.docs tomcat的介绍和操作文档等 2.examples 小程序示例 3.host-manager host管理 4.manager(重点) 进行 Server Status 和 Appli ...

  5. 天才ACM

    天才ACM 给定一个整数m,定义一个集合的权值为从这个集合中任意选出m对数(不够没关系,选到尽可能选,凑不成对的舍去),每对数两个数的差的平方的和的最大值. 现在给出一个数列\(\{a_i\}\),询 ...

  6. python3和python2编码拾遗

    py2编码 tr和unicode str和unicode都是basestring的子类.严格意义上说,str其实是字节串,它是unicode经过编码后的字节组成的序列.对UTF-8编码的str'苑'使 ...

  7. axios HTTP 400后,error没有详细信息

    参考网址:axios怎么获取到error中的状态值,具体信息 error.response

  8. http://www.2cto.com/ 红黑联盟

    http://www.2cto.com/ 红黑联盟,一个不错的学习或者开阔眼界的网站,内部由中文书写.比较适合国人.

  9. 使用Navicat连接管理远程linux服务器上的mysql数据库

    第一步:选择连接,选择mysql 第二步:填写下面弹出框的信息:连接名随便写,主机名或IP地址:写上服务器的ip.  端口不变  用户名不变.  密码:输入服务器数据库的密码12345678. 接着测 ...

  10. 解析Asp.net Core中使用Session的方法

    2017年就这么悄无声息的开始了,2017年对我来说又是特别重要的一年. 元旦放假在家写了个Asp.net Core验证码登录, 做demo的过程中遇到两个小问题,第一是在Asp.net Core中引 ...