2009-08-06 10 views
18

J'ai un fichier XML comme suit:JAVA element.getElementsByTagName Limiter à haut niveau

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

Le code XML Java utilisant DOM est comme suit:

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

Cela me donnera tous les éléments "link" incluant le niveau supérieur et celui du noeud "image".

Existe-t-il un moyen d'obtenir simplement les balises "link" pour rootNode dans un niveau et pas deux comme c'est le cas pour le lien d'image? C'est, je veux juste le http://rootlink/ "lien".

Répondre

3

Si vous pouvez utiliser JDOM à la place, vous pouvez le faire:

element.getChildren("link"); 

Avec Dom standard, le plus proche, vous pouvez obtenir est de parcourir la liste des nœuds enfants (en appelant GetChildNodes() et vérifier chaque élément (i .) du NodeList, choisissant les noeuds avec le nom correspondant

+0

J'ai pensé à JDOM, mais j'ai écrit beaucoup de code avec DOM. Je dois regarder le niveau d'effort pour convertir. Mais n'y a-t-il aucun moyen de le faire avec DOM? – user152090

+0

Je ne pense pas qu'il existe un moyen pratique de le faire. mais vous pouvez créer une méthode qui reçoit les appels getChildNodes(), vérifie le nom de chaque élément, ajoute les éléments à une nouvelle NodeList, puis retourne la NodeList. Utilisez cette méthode partout où vous avez besoin d'obtenir les enfants nommés. Ou mordre la balle et utiliser JDom, je trouve que c'est beaucoup plus facile à gérer. –

+0

Merci. Je vais regarder dans les différentes solutions proposées. Merci pour la réponse rapide. – user152090

12

Vous pouvez utiliser XPath:

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

Merci pour la réponse rapide. – user152090

10

je ne pouvais pas trouver des méthodes pour le faire e ither j'ai donc écrit cette fonction d'assistance,

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

La boucle if est toujours vraie. J'ai essayé comme ceci ... pour (int nodeCnt = 0; nodeCnt

+1

J'ai atterri ici en cherchant un moyen de le faire en Javascript. Cette réponse m'a aidé. J'ai commencé avec ce code et l'ai transformé en JS. 'function getChildrenByTagName (parent, nom) { var nodeList = []; pour (enfant var = parent.firstChild;! Enfant = null; enfant = child.nextSibling) { \t if (child.nodeType == 1 && nom == child.nodeName) { nodeList.push (enfant); } } return nodeList; } ' – curioustechizen

+0

PHP: fonction getChildrenByTagName ($ parent, $ nom) { $ nodeList = array(); foreach ($ parent-> getElementsByTagName ($ name) as $ child) { if ($ enfant-> nodeType == 1) { array_push ($ nodeList, $ enfant); } } return $ nodeList; } – thethakuri

0

J'ai écrit cette fonction pour obtenir la valeur de noeud par tagName, limiterai à haut niveau

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

Je sais que c'est une question ancienne, mais néanmoins je une solution alternative à ajouter.

Ce n'est pas le plus efficace, mais fonctionne:

Obtenez tous les enfants qui utilisent getElementsByTagName, alors il suffit de vérifier chacun a le même parent à celui que vous avez commencé.

Je l'utilise parce que j'ai un ensemble de résultats, chaque résultat peut avoir des résultats imbriqués à l'intérieur. Quand j'appelle mon constructeur de résultat, j'ai besoin d'ajouter des résultats imbriqués, mais comme ils chercheront eux-mêmes leurs propres enfants, je ne veux pas ajouter d'enfants au niveau actuel (leur parent les ajoutera).

Exemple:

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

Hope this helps.

Questions connexes