八、处理命令空间
一般一个规范xml都会有命名空间的定义,例如:
<?xml version="1.0" encoding="UTF-8"?> <tg:bookstore xmlns:tg="http://www.tibco.com/cdc/liugang" xmlns:ns="http://www.tibco.com/cdc/liugang/ns"> <ns:book> <tg:title>Hello</tg:title> </ns:book> </tg:bookstore>
bookstore的命名空间就是xmlns:tg代表的值;book的命名空间就是xmlns:ns代表的值。
xpath中定义了与节点名和命名空间有关的三个函数:
- local-name()
- namespace-uri()
- name()
例如要查找所有在当前文档中定义的,元素的local名为book的结点,则如下:
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xpath = xPathFactory.newXPath();
XPathExpression compile = xpath.compile("//*[local-name()='book']");
NodeList list = (NodeList) compile.evaluate(document,XPathConstants.NODESET);
如果元素定义了命名空间,则使用xpath查找时也必须指定在同一个命名空间中,即便元素使用的是缺省的命名空间,刚查找也需要定义缺省的命名空间。
例如文档:
<?xml version="1.0" encoding="UTF-8"?> <bookstore xmlns="http://www.tibco.com/cdc/liugang" xmlns:tg="http://www.tibco.com/cdc/liugang/tg" xmlns:ns="http://www.tibco.com/cdc/liugang/ns"> <ns:book> <tg:title>Hello</tg:title> </ns:book> <computer> <id>ElsIOIELdslke-1233</id> </computer> </bookstore>
定义了三个命名空间:缺省的;xmlns:tg;xmlns:ns。
要使用命名空间,我们需要设置XPath的命名空间上下文:NamespaceContext。这是一个接口类型,我们需要自定义去实现它。例如对应于上文档的三个命名空间,可以如下实现:
class CustomNamespaceContext implements NamespaceContext{
public String getNamespaceURI(String prefix) {
if(prefix.equals("ns")){
return "http://www.tibco.com/cdc/liugang/ns";
}else if(prefix.equals("tg")){
return "http://www.tibco.com/cdc/liugang/tg";
}else if(prefix.equals("df")){
return "http://www.tibco.com/cdc/liugang";
}
return XMLConstants.NULL_NS_URI;
}
public String getPrefix(String namespaceURI) {
return null;
}
public Iterator getPrefixes(String namespaceURI) {
return null;
}
}
方法名都非常直观。这里只实现第一个方法。
这样,如果要查找命名空间是缺省,元素名为computer的所有元素,可以如下实现:
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xpath = xPathFactory.newXPath();
xpath.setNamespaceContext(new CustomNamespaceContext());
XPathExpression compile = xpath.compile("//df:computer");
NodeList list = (NodeList) compile.evaluate(document,XPathConstants.NODESET);
for(int i = 0;i<list.getLength();i++){
Node item = list.item(i);
System.out.println(item.getNodeName()+" "+item.getNodeValue());
}
九、其他
除此之外,在java中,还可以定义扩展的函数解释器和变量解释器,看XPath的方法:
/**
* <p>Establish a variable resolver.</p>
*
* <p>A <code>NullPointerException</code> is thrown if <code>resolver</code> is <code>null</code>.</p>
*
* @param resolver Variable resolver.
*
* @throws NullPointerException If <code>resolver</code> is <code>null</code>.
*/
public void setXPathVariableResolver(XPathVariableResolver resolver);
/**
* <p>Establish a function resolver.</p>
*
* <p>A <code>NullPointerException</code> is thrown if <code>resolver</code> is <code>null</code>.</p>
*
* @param resolver XPath function resolver.
*
* @throws NullPointerException If <code>resolver</code> is <code>null</code>.
*/
public void setXPathFunctionResolver(XPathFunctionResolver resolver);
具体的可以参看API帮助