Операции на узлах - PullRequest
       11

Операции на узлах

2 голосов
/ 05 февраля 2012

Я изучаю API Java XML.Я использую 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" или, если я пытаюсь получить значение: ничего

Я был бы признателен за любую помощь, так как я являюсь абсолютным новичком во всех этих вопросах и упал немного потерянно:

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 ]

3 голосов
/ 05 февраля 2012

Я получаю количество узлов второго уровня (почему-то 5, а не 2)

Это потому, что DOM сохраняет пробелы. Итак, что у вас есть на этом уровне:

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

т.е. 5 узлов.

когда я пытаюсь получить имя узла с индексом 0, я получаю "#text"

Если вы прочитаете javadoc для Node.getName(), вы поймете почему. Узел с индексом 0 является узлом пробела, а getName() на текстовом узле возвращает аппаратную строку #text.

если я пытаюсь получить значение: ничего не отображается

Опять же, это потому, что это текстовый узел только для пробелов.

Вам нужно выбрать узлы с индексами 1 и 3, если вам нужен доступ к элементам <staff>.

1 голос
/ 05 февраля 2012

Как показывает размер NodeList, компания-элемент имеет 5 дочерних узлов. Эти дочерние узлы:

  1. пустой текстовый узел перед первым штатным узлом
  2. первый штатный узел
  3. пустой текстовый узел между двумя штатными узлами
  4. второй штатный узел
  5. пустой текстовый узел после второго штатного узла

Важность этих текстовых узлов может быть более заметна, если вы думаете, следующий вид документа:

<?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");

Ответ на вопрос после редактирования: Ваш второй подход:

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

терпит неудачу, потому что вы вызываете метод для неправильного элемента уровня. Как видите, вы пытаетесь получить имя дочернего элемента companyElement. Но нет ни одного. Как и в начале, у компании есть пять дочерних узлов, которые были перечислены ранее. Если вас интересуют дочерние узлы staff-element, то вы должны использовать их как элемент персонала, что-то вроде:

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

Если у вас есть время для изучения основ этого предмета, чтение этой главы из учебника JAXP может быть полезным. Если вам нужен пример, который хорошо подходит для вашего случая, его можно найти по здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...