2013-08-26 2 views
0

Я пытаюсь построить и запрос XPath для выбора элемента в соответствии с атрибутом другого элемента. Мой XML выглядит следующим образом:XPath расширенный поиск на основе другого атрибута XML

<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> 

В основном то, что я хочу, чтобы выбрать Atom, который @key атрибут ссылается Облигацию в @ atomref1 атрибутов у @ atomref2 облигации. Вот и все, находясь в узле Bond, получите элемент Atom, на который ссылается этот Bond.

То, что я пытался что-то вроде этого:

../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 (найти атомы, которые участвуют в , этот конкретный), потому что у вас нет доступа к внешнему контексту, когда вы находитесь внутри предиката на atom. Если вы были в 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); 
Смежные вопросы