JAVA element.getElementsByTagName Ограничить до верхнего уровня - PullRequest
20 голосов
/ 07 августа 2009

У меня есть XML-файл следующим образом:

<rootNode>
    <link>http://rootlink/</link>
    <image>
        <link>http://imagelink/</link>
        <title>This is the title</title>
    </image>
</rootNode>

XML-код Java с использованием DOM выглядит следующим образом:

NodeList rootNodeList = element.getElementsByTagName("link");

Это даст мне все элементы «ссылки», включая верхний уровень и элемент внутри узла «изображение».

Есть ли способ просто получить теги "ссылка" для rootNode в пределах одного уровня, а не два, как в случае ссылки на изображение? То есть я просто хочу http://rootlink/ "ссылку".

Ответы [ 5 ]

13 голосов
/ 07 августа 2009

Вы можете использовать XPath :

XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
NodeList links = (NodeList) xpath.evaluate("rootNode/link", element,
    XPathConstants.NODESET);
11 голосов
/ 07 августа 2009

Я не мог найти никаких методов для этого, поэтому я написал эту вспомогательную функцию,

 public static List<Element> getChildrenByTagName(Element parent, String name) {
    List<Element> nodeList = new ArrayList<Element>();
    for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) {
      if (child.getNodeType() == Node.ELEMENT_NODE && 
          name.equals(child.getNodeName())) {
        nodeList.add((Element) child);
      }
    }

    return nodeList;
  }
3 голосов
/ 07 августа 2009

Если вместо этого вы можете использовать JDOM , вы можете сделать это:

element.getChildren("link");

В стандартном Dom самое близкое, что вы можете получить, - это итерировать список дочерних узлов (вызывая getChildNodes () и проверяя каждый элемент (i) из NodeList, выбирая узлы с соответствующим именем.

1 голос
/ 13 июня 2014

Я знаю, что это старый вопрос, но, тем не менее, я могу добавить альтернативное решение.

Это не самый эффективный, но работает:

Получите всех детей, используя getElementsByTagName, затем просто убедитесь, что у каждого из них один и тот же родительский элемент с тем, с которого вы начали.

Я использую это, потому что у меня есть набор результатов, каждый результат может иметь результаты, вложенные в него. Когда я вызываю конструктор Result, мне нужно добавить любые вложенные результаты, но, поскольку они сами будут искать своих собственных детей, я не хочу добавлять дочерние элементы на текущий уровень (их родитель добавит их).

Пример:

NodeList children = resultNode.getElementsByTagName("result");
for(int i = 0; i<children.getLength(); i++){
   // make sure not to pick up grandchildren.
   if(children.item(i).getParentNode().isSameNode(resultNode)){
        addChildResult(new Result((Element)children.item(i)));
    }
}

Надеюсь, это поможет.

0 голосов
/ 07 августа 2013

Я написал эту функцию, чтобы получить значение узла по tagName, ограничиться верхним уровнем

public static String getValue(Element item, String tagToGet, String parentTagName) {
    NodeList n = item.getElementsByTagName(tagToGet);
    Node nodeToGet = null;
    for (int i = 0; i<n.getLength(); i++) {
        if (n.item(i).getParentNode().getNodeName().equalsIgnoreCase(parentTagName)) {
            nodeToGet = n.item(i);
        }
    }
    return getElementValue(nodeToGet);
}

public final static String getElementValue(Node elem) {
    Node child;
    if (elem != null) {
        if (elem.hasChildNodes()) {
            for (child = elem.getFirstChild(); child != null; child = child
                    .getNextSibling()) {
                if (child.getNodeType() == Node.TEXT_NODE) {
                    return child.getNodeValue();
                }
            }
        }
    }
    return "";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...