获取另一个节点的子节点,给定节点名称。

38

我有这样一个XML:

<documentslist>
  <document>
    <docnumber>1</docnumber>
    <docname>Declaration of Human Rights</docname>
    <aoo>lib</aoo>
  </document>
  <document>
    <docnumber>2</docnumber>
    <docname>Fair trade</docname>
    <aoo>lib</aoo>
  </document>
  <document>
    <docnumber>3</docnumber>
    <docname>The wars for water</docname>
    <aoo>lib</aoo>
  </document>
  <!-- etc. -->
</documentslist>

I have this code:

//XML parsing
Document docsDoc = null;
try {
    DocumentBuilder db = dbf.newDocumentBuilder();
    docsDoc = db.parse(new InputSource(new StringReader(xmlWithDocs)));
}
catch(ParserConfigurationException e) {e.printStackTrace();}
catch(SAXException e) {e.printStackTrace();}
catch(IOException e) {e.printStackTrace();}
//retrieve document elements
NodeList docs = docsDoc.getElementsByTagName("document");

if (docs.getLength() > 0){
    //print a row for each document
    for (int i=0; i<docs.getLength(); i++){
        //get current document
        Node doc = docs.item(i);
        //print a cell for some document children
        for (int j=0; j<columns.length; j++){
            Node cell;
            //print docname
            cell = doc.getElementsByTagName("docname").item(0); //doesn't work
            System.out.print(cell.getTextContent() + "\t");
            //print aoo
            cell = doc.getElementsByTagName("aoo").item(0); //doesn't work
            System.out.print(cell.getTextContent() + "\t");
        }
        System.out.println();
    }
}

但是,正如你所知道的,Node没有getElementsByTagName方法...只有Document有这个方法。但我不能使用docsDoc.getElementsByTagName("aoo"),因为它会返回所有<aoo>节点,而不仅仅是我正在检查的<document>节点中存在的节点。

我该怎么做呢?谢谢!


Google或维基百科:递归。 - Martijn Courteaux
4个回答

53

如果Node不仅仅是一个节点,而实际上是一个Element(也可能是属性或文本节点),那么您可以将其转换为Element并使用getElementsByTagName


3
这并非完全正确。Element实际上是扩展了Node,而不是反过来。我不会仅依赖于Node始终是Element,确保在使用instanceof检查Node类型后进行转换,就像Yeameen建议的那样。参考文献:http://docs.oracle.com/javase/6/docs/api/org/w3c/dom/Element.html - siyb

27

检查Node是否是Dom Element,进行强制类型转换并调用getElementsByTagName()

Node doc = docs.item(i);
if(doc instanceof Element) {
    Element docElement = (Element)doc;
    ...
    cell = doc.getElementsByTagName("aoo").item(0);
}

11
如果(node.getNodeType() == Node.ELEMENT_NODE),则表示节点类型为元素节点。 - djangofan

6
您应该递归地阅读它,前段时间我也有同样的问题,并用以下代码解决:
public void proccessMenuNodeList(NodeList nl, JMenuBar menubar) {
    for (int i = 0; i < nl.getLength(); i++) {
        proccessMenuNode(nl.item(i), menubar);
    }
}

public void proccessMenuNode(Node n, Container parent) {
    if(!n.getNodeName().equals("menu"))
        return;
    Element element = (Element) n;
    String type = element.getAttribute("type");
    String name = element.getAttribute("name");
    if (type.equals("menu")) {
        NodeList nl = element.getChildNodes();
        JMenu menu = new JMenu(name);

        for (int i = 0; i < nl.getLength(); i++)
            proccessMenuNode(nl.item(i), menu);

        parent.add(menu);
    } else if (type.equals("item")) {
        JMenuItem item = new JMenuItem(name);
        parent.add(item);
    }
}

也许您可以将其适应于您的情况。

0
//xn=list of parent nodes......                
foreach (XmlNode xn in xnList)
{                                           
    foreach (XmlNode child in xn.ChildNodes) 
    {
        if (child.Name.Equals("name")) 
        {
            name = child.InnerText; 
        }
        if (child.Name.Equals("age"))
        {
            age = child.InnerText; 
        }
    }
}

2
请就您的代码中解决问题的亮点发表评论,这将有助于使其更易理解。 - RinoTom
1
这不像是Java。 - ceving

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接