2009-08-06 14 views
18

Tengo un archivo XML de la siguiente manera:JAVA element.getElementsByTagName Restringir a nivel superior

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

El código Java XML utilizando DOM es el siguiente:

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

Esto me dará toda la elementos de "enlace" que incluyen el nivel superior y el que está dentro del nodo de "imagen".

¿Hay alguna forma de obtener las etiquetas de "enlace" para rootNode en un nivel y no dos como en el caso del enlace de imagen? Es decir, solo quiero el http://rootlink/ "enlace".

Respuesta

3

Si puede utilizar JDOM lugar, usted puede hacer esto:

element.getChildren("link"); 

Con el estándar Dom el más cercano que puedes conseguir es para repetir la lista de nodos secundarios (llamando getChildNodes() y revisando cada punto (i .) del NodeList, eligiendo los nodos con el nombre coincidente

+0

Pensé en JDOM, pero he escrito un montón de código con DOM. Tengo que mirar el nivel de esfuerzo para convertir. ¿Pero no hay forma de hacerlo con DOM? – user152090

+0

No creo que haya una manera conveniente de hacerlo. pero puede crear un método que reciba llamadas getChildNodes(), verifique el nombre de cada elemento, agregue los elementos a una nueva NodeList y luego devuelva NodeList. Use ese método donde sea que necesite obtener los niños nombrados. O muerde la bala y usa JDom, me resulta mucho más fácil de tratar. –

+0

Gracias. Analizaré las diferentes soluciones sugeridas. Gracias por la rápida respuesta. – user152090

12

usted podría utilizar XPath:

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

Gracias por la respuesta rápida. – user152090

10

no se han encontrado métodos para hacer que el correo ither así que escribí esta función auxiliar,

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

El bucle if es siempre verdadero. intenté así ... para (int nodeCnt = 0; nodeCnt

+1

Aterricé aquí buscando una forma de hacerlo en Javascript. Esta respuesta me ayudó. Empecé con este código y lo convertí en JS. 'function getChildrenByTagName (principal, nombre) { var nodeList = []; for (var = parent.firstChild niño;! Niño = null; niño = child.nextSibling) { \t si (child.nodeType == == Nombre 1 && child.nodeName) { nodeList.push (niño); } } return nodeList; } ' – curioustechizen

+0

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

0

escribí esta función para obtener el valor del nodo por tagName, restrinja a nivel superior

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

Sé que esto es una cuestión de edad, pero no obstante tengo una solución alternativa para agregar.

No es el más eficiente, pero funciona:

obtener todos los niños que utilizan getElementsByTagName, a continuación, simplemente marque cada uno tiene la misma matriz a la que empezó.

Lo uso porque tengo un conjunto de resultados, cada resultado puede tener resultados anidados dentro de él. Cuando llamo al constructor de resultados, necesito agregar resultados anidados, pero como ellos mismos buscarán sus propios hijos, no quiero agregar hijos al nivel actual (su padre los agregará).

Ejemplo:

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

Espero que esto ayude.

Cuestiones relacionadas