2013-08-26 72 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);