2009-08-06 6 views
18

Ich habe eine XML-Datei wie folgt:JAVA element.getElementsByTagName nach oben einschränken Ebene

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

Die XML-Java-Code DOM ist wie folgt:

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

Das gibt mir all die "link" -Elemente einschließlich der obersten Ebene und der innerhalb des "image" -Knotens.

Gibt es eine Möglichkeit, nur die "Link" -Tags für rootNode innerhalb einer Ebene zu erhalten und nicht zwei, wie es bei der Bildverknüpfung der Fall ist? Das heißt, ich möchte nur die http://rootlink/ "Link".

Antwort

3

Wenn Sie JDOM stattdessen verwenden können, können Sie dies tun:

element.getChildren("link"); 

Mit Standard-Dom in der Nähe Sie erhalten können, ist das Kind Knoten Liste iterieren (von getChildNodes() und überprüft jedes Element (i Aufruf .) der NodeList, die Knoten mit dem passenden Namen herauszupicken

+0

Ich dachte über JDOM nach, aber ich habe viel Code mit DOM geschrieben. Ich muss mir das Maß an Aufwand ansehen, um zu konvertieren. Aber gibt es keine Möglichkeit, dies mit DOM zu tun? – user152090

+0

Ich glaube nicht, dass es einen bequemen Weg gibt, es zu tun. Sie können jedoch eine Methode erstellen, die getChildNodes() aufruft, den Namen jedes Elements überprüft, die Elemente zu einer neuen NodeList hinzufügt und dann die NodeList zurückgibt. Verwenden Sie diese Methode überall dort, wo Sie die benannten untergeordneten Elemente benötigen. Oder beißt in die Kugel und benutze JDom, ich finde es viel einfacher damit umzugehen. –

+0

Danke. Ich werde die verschiedenen vorgeschlagenen Lösungen betrachten. Danke für die schnelle Antwort. – user152090

12

könnten Sie XPath verwenden:

XPathFactory xpathFactory = XPathFactory.newInstance(); 
XPath xpath = xpathFactory.newXPath(); 
NodeList links = (NodeList) xpath.evaluate("rootNode/link", element, 
    XPathConstants.NODESET); 
+0

Danke für die schnelle Antwort. – user152090

10

ich alle Methoden nicht, dass e finden konnten, zu tun ither so schrieb ich diese Hilfsfunktion,

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; 
    } 
+0

Die if-Schleife ist immer wahr. Ich probierte so ... für (int nodeCnt = 0; nodeCnt

+1

Ich bin hier gelandet auf der Suche nach einer Möglichkeit, dies in Javascript zu tun. Diese Antwort hat mir geholfen. Ich habe mit diesem Code angefangen und ihn in JS umgewandelt. 'Funktion getChildrenByTagName (Eltern, Name) { var nodeList = []; für (var child = parent.firstChild;! Kind = null; Kind = child.nextSibling) { \t if (child.nodeType == 1 && name == child.nodeName) { nodeList.push (Kind); } } Rückgabe nodeList; } ' – curioustechizen

+0

PHP: Funktion getChildrenByTagName ($ parent, $ name) { $ nodeList = array(); foreach ($ parent-> getElementsByTagName ($ name) als $ child) { if ($ child-> nodeType == 1) { array_push ($ knotenliste, $ untergeordnet); } } Rückgabe $ nodeList; } – thethakuri

0

ich diese Funktion schrieb den Knotenwert von tagName zu bekommen, beschränken auf Top-Level-

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 ""; 
} 
1

Ich weiß, dass dies eine alte Frage, aber trotzdem habe ich eine alternative Lösung zum Hinzufügen.

Es ist nicht die effizienteste, aber funktioniert:

Holen Sie sich alle Kinder getElementsByTagName verwenden, dann überprüfen Sie einfach jeder zum einen die gleichen Eltern hat mit Ihnen gestartet.

Ich benutze dies, weil ich eine Reihe von Ergebnissen habe, jedes Ergebnis kann Ergebnisse darin verschachtelt haben. Wenn ich meinen Result-Konstruktor aufruft, muss ich irgendwelche verschachtelten Ergebnisse hinzufügen, aber da sie selbst nach ihren eigenen Kindern suchen, möchte ich keine Kinder zur aktuellen Ebene hinzufügen (ihre Eltern fügen sie hinzu).

Beispiel:

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))); 
    } 
} 

Hoffnung, das hilft.

Verwandte Themen