2013-08-26 41 views
0

我正在尝试构建和XPath查询以根据另一个元素的属性选择元素。我的XML是这样的:基于XML其他属性的XPath高级搜索

<datadoc> 
    <data> 
    <molecule coorddimension="3"> 
     <properties> 
     <property name="Mol2_MolInfo_Name" type="stringvalue"> 
      <val>ZINC01532215_1</val> 
     </property>   
     </properties> 
     <atom key="0" element="6" x="8.2965" y="42.3268" z="14.1097"> 
     <properties> 
      <property name="AtomName" type="stringvalue"> 
      <val>C1</val> 
      </property>   
     </properties> 
     </atom>  
     <atom key="9" element="6" x="7.3131" y="43.2537" z="13.9462"> 
     <properties> 
      <property name="AtomName" type="stringvalue"> 
      <val>C10</val> 
      </property>   
     </properties> 
     </atom>    
     <bond atomref1="0" atomref2="9" type="double"> 
     <properties> 
      <property name="BondSybylType" type="stringvalue"> 
      <val>ar</val> 
      </property> 
     </properties> 
     </bond> 
    </molecule> 
    </data> 
    </datadoc> 

基本上我想要的是选择哪个@key属性由邦德@引用atomref1Ÿ@ atomref2债券的属性了Atom。就是这样,在Bond节点中,获取该Bond引用的Atom元素。

我想什么是这样的:

../atom[@key = ./@atomref1] 

我用..因为当我做我在邦德节点查询,但似乎并没有工作。任何想法,如果可以用XPath完成?

谢谢。

+0

如果可以,请发布您的Java代码或其摘录。另外,发布一个“更复杂”的XML提取,带有多个'bond' –

回答

0

试试这个表达式:

.//atom[@key=../bond/@atomref1] 

如果你想匹配@ atomref2:

.//atom[@key=../bond/@atomref2] 

如果你想同时<atom>

.//atom[@key=../bond/@atomref1 or @key=../bond/@atomref2] 
+0

你可以参考一个好的'xpath2.0'和'xpath1.0'支持的测试工具(离线)吗? –

+0

您的意思是作为对答案的编辑? –

+0

不,不,我要求自己,因为我在我的Ubuntu笔记本电脑中,不支持许多xpath表达式,因此我正在寻找一个先进的.. –

0

我不认为你可以在纯xpath中实现这一点(查找参与这个特定的原子债券),因为当您位于​​的谓词中时,您无权访问外部上下文。如果你是在XSLT您可以使用current()功能,它提供到外部上下文的引用:

../atom[@key = (current()/@atomref1| current()/@atomref2)] 

但是这是一个XSLT特定的功能,在标准的XPath不可用。

根据您如何执行XPath表达式,您可能能够提供变量绑定。由于您在评论中声明您正在使用Java,因此以下是使用javax.xml.xpath的示例:

class MapVariableResolver extends HashMap<String, Object> implements XPathVariableResolver { 
    public Object resolveVariable(QName name) { 
    return get(name.getLocalPart()); 
    } 
} 

XPath xp = XPathFactory.newInstance().newXPath(); 
MapVariableResolver mvr = new MapVariableResolver(); 
xp.setXPathVariableResolver(mvr); 

Node bond = // ... however you get the bond element 
mvr.put("current", bond); 
NodeList atoms = (NodeList)xp.evaluate(
    "../atom[@key = ($current/@atomref1| $current/@atomref2)]", 
    bond, 
    XPathConstants.NODESET);