节点上的操作

时间:2012-02-05 11:14:41

标签: java xml dom nodes

我正在学习Java XML API。我正在使用DOM。

我在文档内部进行基本导航时遇到问题。这是我正在使用的XML文件:

<?xml version="1.0"?>
<company>
    <staff>
        <firstname>test</firstname>
        <lastname>test2</lastname>
        <nickname>test3</nickname>
        <salary>test4</salary>
    </staff>
    <staff>
        <firstname>test5</firstname>
        <lastname>test6</lastname>
        <nickname>test7</nickname>
        <salary>test8</salary>
    </staff>
</company>

这是我到目前为止的代码,它应该获取父节点及其子节点的名称:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder  = factory.newDocumentBuilder();
Document document = builder.parse(new File(pathtothefile));

Element topLevelElement = document.getDocumentElement();
NodeList secondLevelElements = topLevelElement.getChildNodes();

System.out.println("Top level element: " + topLevelElement.getNodeName());
System.out.println("Number of second level nodes: " + secondLevelElements.getLength());
System.out.println("Node at index 0: " + secondLevelElements.item(0).getNodeValue());

我得到二级节点的数量(由于某种原因5,而不是2),但是当我尝试在索引0处获取节点的名称时,我得到“#text”或者如果我尝试获取值:没有显示器。

我会感激任何帮助,因为我是所有这些人的初学者,并且有点迷失:)

更新1:

这是新代码:

Element companyElement = document.getDocumentElement();
NodeList staffElements = companyElement.getElementsByTagName("staff");
NodeList firstNameElements = companyElement.getElementsByTagName("firstname");
NodeList lastNameElements = companyElement.getElementsByTagName("lastname");
NodeList nicknameElements = companyElement.getElementsByTagName("nickname");
NodeList salaryElements = companyElement.getElementsByTagName("salary");

System.out.println("Top level element: " + companyElement.getNodeName());
System.out.println("----");
System.out.println("Next nodes' level name: " + staffElements.item(0).getNodeName());
System.out.println("Next nodes' level number: " + staffElements.getLength());
System.out.println("----");
System.out.println("Person No. 1");
System.out.println("First name: " + firstNameElements.item(0).getNodeValue());
System.out.println("Last name: " + lastNameElements.item(0).getNodeValue());
System.out.println("Nickname: " + nicknameElements.item(0).getNodeValue());
System.out.println("Salary: " + salaryElements.item(0).getNodeValue());
System.out.println("----");
System.out.println("Person No. 2");
System.out.println("First name: " + firstNameElements.item(1).getNodeValue());
System.out.println("Last name: " + lastNameElements.item(1).getNodeValue());
System.out.println("Nickname: " + nicknameElements.item(1).getNodeValue());
System.out.println("Salary: " + salaryElements.item(1).getNodeValue());

2 个答案:

答案 0 :(得分:3)

  

我得到了二级节点的数量(由于某种原因5,而不是2)

这是因为DOM保留了空白区域。所以你在那个级别所拥有的是:

[whitespace][staff element][whitespace][staff element][whitespace]

即。 5个节点。

  

当我尝试在索引0处获取节点的名称时,我得到“#text”

如果您为Node.getName()阅读the javadoc,就会知道原因。索引0处的节点是空白节点,文本节点上的getName()返回硬连线字符串#text

  

如果我尝试获取值:没有显示

同样,那是因为它只是一个空白文本节点。

如果需要访问<staff>元素,则需要获取索引1和3处的节点。

答案 1 :(得分:1)

正如NodeList的大小所告知的那样,company-element有5个子节点。这些子节点是:

  1. 在第一个staff-node
  2. 之前的空文本节点
  3. first staff-node
  4. 两个职员节点之间的空文本节点
  5. 第二名员工节点
  6. 第二个人员节点之后的空文本节点
  7. 如果您考虑使用以下类型的文档,这些文本节点的重要性可能更明显:

    <?xml version="1.0"?>
    <company>
        text before first staff-node
        <staff>
            <firstname>test</firstname>
            <lastname>test2</lastname>
            <nickname>test3</nickname>
            <salary>test4</salary>
        </staff>
        text between staff-nodes
        <staff>
            <firstname>test5</firstname>
            <lastname>test6</lastname>
            <nickname>test7</nickname>
            <salary>test8</salary>
        </staff>
        text after second staff-node
    </company>
    

    如果您希望Nodelist只包含人员节点,您可以使用以下内容:

    NodeList staffNodes = topLevelElement.getElementsByTagName("staff");
    

    Anser在编辑后提问: 你的第二种方法:

    NodeList firstNameElements = companyElement.getElementsByTagName("firstname");
    

    失败,因为你正在调用错误级别元素的方法。如您所见,您正在尝试获取companyElement的firstname子元素。但没有。与开始时一样,公司有五个以前列出的子节点。如果您对staff元素的子节点感兴趣,那么您必须使用staff元素中的那些节点,例如:

    org.w3c.dom.Element n = (org.w3c.dom.Element) staffNodes.item(i);
    NodeList firstNameElements = n.getElementsByTagName("firstname");
    

    如果您有时间学习该主题的基础知识,从JAXP教程中阅读此chapter会很有用。如果您只想要与您的案例匹配良好的示例,可以从here

    找到它