對於 XML 文件中不帶命名空間(NameSpace) 的節點,如
<blog_Content>
用 JDOM 的 XPath 來搜索這個節點時可用下面之中任一代碼:
① List<Element> elements = XPath.selectNodes(document,"//blog_Content");
② XPath xpath = XPath.newInstance("//blog_Content");
List<Element> elements = xpath.selectNodes(document);
但是如果是查找帶命名空間的節點,如
<blogns:blog_Content XMLns:blogns="x-schema:#Schema2">
<blogns:Title>Quartz Job Scheduling Framework[翻譯]第一章. 企業應用中的作業調度</blogns:Title>
..............................................
還是用前面那兩種方法可就查不到 blog_Content 節點了,即使是寫成
List<Element> elements = XPath.selectNodes(document,"//blogns:blog_Content");
或者對於 <blogns:Title> 寫成
List<Element> elements = XPath.selectNodes(document,"//blogns:Title");
都是檢索不到元素的,elements.size() 為 0。
這時候,我們需要明確的指定你的 XPath 實例所要用的 NameSpace,用 XPath 的 addNamespace() 方法,操作代碼如下:
XPath xpath = XPath.newInstance("//blogns:blog_Content");
xpath.addNamespace("blogns","x-schema:#Schema2");
List<Element> elements = xpath.selectNodes(document);
這樣就能檢索到 <blogns:blog_Content> 節點了,對於 <blogns:Title> 也是一樣的做法。
可是對於使用默認命名空間(Default Namespace) 的節點又該如何檢索呢?例如檢索下面 XML 的 <blog_Content> 節點
<blog_Content XMLns="x-schema:#Schema2">
<Title>Quartz Job Scheduling Framework[翻譯]第一章. 企業應用中的作業調度</Title>
.................................
以一個較為常規的思維方式吧,Default Namespace 大概就是 "" 空字符串吧,那麼是不是寫成
XPath xpath = XPath.newInstance("//blog_Content");
xpath.addNamespace("","x-schema:#Schema2");
List<Element> elements = xpath.selectNodes(document);
就能找到節點了呢?很遺憾,這裡的 elements.size() 等於 0,檢索失敗。
JDOM 要求,不知是否是所有 XML 解析 API 都有這樣的規范,即使使用的是默認命名空間,在用 XPath 檢索時也必須給這個默認命名空間指定一個名字,我們這裡就選 "default" 吧,你可以任意指定一個不沖突的名字,不要被這裡的 "default" 誤導了只能用它。所以檢索 <blog_Content> 的代碼就是:
XPath xpath = XPath.newInstance("//default:blog_Content");
xpath.addNamespace("default","x-schema:#Schema2");
List<Element> elements = xpath.selectNodes(document);
這樣你就能檢索到你要的節點了。
以上的 XML 是節選自 BlogJava 博客的日志備份數據文件(BlogJava 管理後台,點 "備份數據" 保存下來的 MyBlogData.XML)。
先告訴大家一個消息,我已經把 《Quartz Job Scheduling Framework 中文教程.chm》制作完成,很快就會拿出來與大家分享。制作這個 CHM 的方法就是從我的日志備份文件 MyBlogData.XML 中用 JDOM XPath 讀出所有的 Quartz Job Scheduling Framework 翻譯日志,排序,然後用模板生成一個個 Html 文件,再用 Visual CHM 裡的工程,一編譯就行,只要博客上的日志內容有變,馬上能生成新版的 CHM 文件。
下面附上一個列舉出日志備份文件 MyBlogData.XML 中所有本站發布日志的標題的程序:
package com.unmi;
import Java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;
/**
* JDOM 使用 XPath 查找帶 NameSpace 的節點
* @author Unmi
*/
public class XPathWithNS {
/**
* @param args
* @throws Exception
* @throws Exception
*/
public static void main(String[] args) throws Exception {
SAXBuilder builder = new SAXBuilder(false);
Document document = builder.build("D:/Unmi/MyBlogData.XML");
//找出在本站原創的日志,PostType='1' 應該就這意義
XPath xpath = XPath.newInstance("//default:blog_Content[default:PostType='1']");
//列出所有Quartz Job Scheduling Framework 翻譯文檔的 XPath
//XPath xpath = XPath.newInstance("//default:blog_Content[contains(default:Title,'Quartz Job Scheduling Framework') and PostType='1']);
xpath.addNamespace("default","x-schema:#Schema2");
List<Element> elements = xpath.selectNodes(document);
for (int i=0;i<elements.size();i++) {
Element element = (Element)elements.get(i);
XPath xpathTitle = XPath.newInstance("default:Title");
xpathTitle.addNamespace("default","x-schema:#Schema2");
String title = ((Element)xpathTitle.selectSingleNode(element)).getTextTrim();
System.out.println((i+1)+". "+title);
}
}
}
package com.unmi;
import Java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;
/**
* JDOM 使用 XPath 查找帶 NameSpace 的節點
* @author Unmi
*/
public class XPathWithNS {
/**
* @param args
* @throws Exception
* @throws Exception
*/
public static void main(String[] args) throws Exception {
SAXBuilder builder = new SAXBuilder(false);
Document document = builder.build("D:/Unmi/MyBlogData.XML");
//找出在本站原創的日志,PostType='1' 應該就這意義
XPath xpath = XPath.newInstance("//default:blog_Content[default:PostType='1']");
//列出所有Quartz Job Scheduling Framework 翻譯文檔的 XPath
//XPath xpath = XPath.newInstance("//default:blog_Content[contains(default:Title,'Quartz Job Scheduling Framework') and PostType='1']);
xpath.addNamespace("default","x-schema:#Schema2");
List<Element> elements = xpath.selectNodes(document);
for (int i=0;i<elements.size();i++) {
Element element = (Element)elements.get(i);
XPath xpathTitle = XPath.newInstance("default:Title");
xpathTitle.addNamespace("default","x-schema:#Schema2");
String title = ((Element)xpathTitle.selectSingleNode(element)).getTextTrim();
System.out.println((i+1)+". "+title);
}
}
}
程序中用到了 XPath 實現類其實是 org.jdom.xpath.JaxenXPath,所以項目中要引用的包有:jdom.jar、saxpath.jar、jaxen-core.jar、jaxen-jdom.jar。也可以使用 XPath 的另一實現類 org.jaxen.jdom.JDOMXPath。