2013-05-01 57 views
1

选择一个节点我有一个XForm的文件使用XPath和JDOM

<?xml version="1.0" encoding="UTF-8"?><h:html xmlns:h="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jr="http://openrosa.org/javarosa"> 
<h:head> 
    <h:title>Summary</h:title> 
    <model> 
     <instance> 
      <data vaultType="nsp_inspection.4.1"> 
       <metadata vaultType="metadata.1.1"> 
        <form_start_time type="dateTime" /> 
        <form_end_time type="dateTime" /> 
        <device_id type="string" /> 
        <username type="string" /> 
       </metadata> 
       <date type="date" /> 
       <monitor type="string" /> 
      </data> 
     </instance> 
    </model> 
</h:head> 

我想使用XPath和JDOM

XPath xpath = XPath.newInstance("h:html/h:head/h:title/"); 

似乎做工精细选择从XForm的数据元素和选择标题元素,但是

XPath xpath = XPath.newInstance("h:html/h:head/model"); 

不选择模型元素。 我想它与命名空间有关。

+0

它看起来像默认的命名空间的问题。这是否有帮助:http://stackoverflow.com/a/6390494/10098?顺便说一句,你的默认命名空间可能是错误的,它应该是http://www.w3.org/2002/xforms如果我没有错误 – wds 2013-05-01 09:18:11

+0

这似乎是做的勾号。 XPath xpath = XPath.newInstance(“// h:model”); tanx @wds为链接。 – zaki 2013-05-01 09:36:49

回答

4

有几件事。你真的应该使用JDOM 2.0.x ...(2.0.5是最新版本)。 2.0.x版本中的XPath API远远好于JDOM 1.x中的XPath API:请参阅https://github.com/hunterhacker/jdom/wiki/JDOM2-Feature-XPath-Upgrade

@ wds对于xforms元素没有正确的名称空间也是正确的......这就是为什么你的XPath正在工作,因为它有相同的命名空间作为带有'h'前缀的xhtml元素。您的代码可能仍然会被破解。

命名空间中的XPath经常混淆的人,因为命名空间的XPath 有一个前缀。即使某些东西是XML中的默认命名空间(没有像'model'元素那样的前缀),也有在XPath中有一个。与在XPath没有前缀查询始终引用“无命名空间”命名空间....(XPath规范:http://www.w3.org/TR/xpath/#node-tests

的QName在节点测试是使用命名空间声明 从扩展成一个扩展名表达上下文。除了不使用用xmlns声明的默认名称空间 :如果QName没有前缀,那么 命名空间URI为null(这是对于开始和结束标签中元素类型名称的扩展完成的方式相同与扩展属性名称的方式相同)。它是 一个错误,如果的QName具有前缀对于其存在在 没有命名空间声明表达上下文

假设@wds是正确的,并为模型元素的命名空间应该是“http://www.w3.org/2002/xforms”然后你的文档中的命名空间解析应该是xmlns =“http://www.w3.org/2002/xforms”。但是,此名称空间是“默认”名称空间,并且XPath查询中无前缀名称空间的URI是“”。

要访问XPath中的http://www.w3.org/2002/xforms命名空间,您必须为其指定一个XPath上下文的前缀,假设xpns(用于xpath命名空间)。在JDOM 1.x中添加与该命名空间:

XPath xpath = XPath.newInstance("/h:html/h:head/xpns:model"); 
xpath.addNamespace(Namespace.getNamespace("xpns", "http://www.w3.org/2002/xforms"); 
Element model = (Element)xpath.selectSingleNode(mydoc) 

请注意如何将添加xpns到查询。另外请注意,我已将'h'/ html引用'锚定'到文档的'/'根目录,这将提高查询评估的性能。

在JDOM 2.x中,XPath API的重要性更好(尽管在某些情况下它看起来可能过于矫枉过正)。

XPathFactory xpf = XPathFactory.instance(); 
XPathExpression<Element> xpath = xpf.compile("/h:html/h:head/xpns:model", 
       Filters.element(), null, 
       Namespace.getNamesace("xpns", "http://www.w3.org/2002/xforms")); 
Element model = xpath.evaluateFirst(mydoc); 

查看更多有关新的XPath API中的JDOM的javadoc 2.X:XPathFactory.compile(...) javadoc