2013-12-10 5 views
0

Я использую библиотеки C++ для разбора xml, а именно quickxml и tinyxml. Ява, встроенная в парсер DOM, абсолютно не имеет для меня никакого смысла. После некоторой борьбы я смог сохранить нужный мне корневой узел, но теперь хочу найти тег с определенным идентификатором.Как найти дочерний элемент с определенным значением атрибута

Вот пример XML:

<?xml version="1.0" encoding="UTF-8"?> 
<adventure title="Test Adventure" author="Tester"> 
    <enemies> 
     <enemy id="e1" difficulty="1">Enemy1</enemy> 
    </enemies> 
    <story> 
     <narration id="n1" action="d1">It's adventure time!</narration> 
     <decision id="d1"> 
      <description>Would you like to participate?</description> 
      <choice action="n2">Yes, please.</choice> 
      <choice action="n3">Not the slightest.</choice> 
     </decision> 
     <narration id="n2" action="end">Great choice!</narration> 
     <narration id="n3" action="end">Okay...</narration> 
    </story> 
</adventure> 

У меня есть <story> узел хранится в Node экземпляра. Оттуда я хочу найти узлы с определенным идентификатором (предположим, узел «n3»).

Я хочу использовать этот метод:

private Node findNode(String id) { 
    Node node = storyNode.getFirstChild(); 
    while (node != null) { 
     Element elem = (Element)node; 
     if (elem.getAttribute("id") == id) { 
      return node; 
     } 
     node = node.getNextSibling(); 
    } 

    return null; 
} 

Это будет мой путь с ++ библиотека C, но это очень далеко от работы ... Я не понимаю, почему я должен типаж для такой простой задачи. Почему у Node нет способа получить атрибуты с указанием имени атрибута. getFirstChild() даже, кажется, не возвращает первого ребенка ...

Класс обертки, который я нашел в Интернете, - это 30 петель в глубину или даже сложнее в использовании. Почему это так сложно? Что я делаю не так?

+0

Как ни странно, это очень похоже на реализация в библиотеках .Net, поэтому я предполагаю, что она основана на рекомендациях от тел стандарта, которые, вероятно, спроектировали решение и никогда не использовали ... – MadProgrammer

+0

@Ma dProgrammer На самом деле это безумие. 'NodeList', который вам нужно пропустить, но не с помощью итератора, потому что единственный способ получить узел - это метод' .item (index) ', который возвращает' Node', который * может * быть «Элемент», и он продолжается и продолжается ... Мне нужны три метода, один из которых может захватить следующий брат, один для возврата определенного дочернего элемента, или первый, если он вызывается без параметра , а третий - для чтения определенного атрибута. Я не мог сделать это более трудным, если бы захотел, что-то действительно не так. – Innkeeper

+0

Лично я написал небольшую библиотеку, чтобы «обернуть» безумие ... и да, я даже написал «IterableNodeList» ... мое чувство кишки было спроектировано и написано инженерами ... Отлично на бумаге .. не столько для людей, которые действительно должны его использовать;) – MadProgrammer

ответ

2

Почему API - это ... удивительный ... придет к тому, почему и как он был разработан. Решение может быть проще, чем вы думаете.

Одна из доступных вам функций - реализация XPath, она рекламируется как язык запросов для XML.

Таким образом, вместо того, чтобы пытаться перебрать каждый узел и каждый дочерний узел, вы могли бы просто использовать что-то вроде //*[@id='n1'], чтобы найти какой-либо узел с атрибутом id, который равен n1 (к примеру).

Использование примера XML и следующий код ...

try { 
    Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("Test.xml")); 
    Node root = doc.getDocumentElement(); 

    XPath xPath = XPathFactory.newInstance().newXPath(); 

    XPathExpression xExpress = xPath.compile("//*[@id='n1']"); 
    NodeList nl = (NodeList)xExpress.evaluate(root, XPathConstants.NODESET); 

    System.out.println("Found " + nl.getLength() + " matches"); 
} catch (SAXException | IOException | ParserConfigurationException | XPathExpressionException ex) { 
    ex.printStackTrace(); 
} 

Это выводимый

Found 1 matches 

Взгляните на XPath еще несколько деталей достаточно

Смежные вопросы