Разбор fake-xml файла в Java - PullRequest
0 голосов
/ 30 июня 2011

Я давно работаю над этой проблемой и не могу понять. Существует определенный файл "xml", который необходимо проанализировать и отобразить на экране:

<office>

<name>joe</name>
<surname>smith</surname>
<name>bob</name>
<surname>black</surname>

.....
</office>

Я нашел несколько отличных примеров кода в сети, но они не работают с XML-файлом, который не настроен правильно, как этот, поэтому, если я добавлю тег, я смогу заставить свой код работать , но проблема в том, что я не могу внести какие-либо изменения в файл "xml".

Это чужой код, который я нашел здесь, который был изменен.

Вот мой код с модами:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;

import org.w3c.dom.*;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException; 

public class ReadAndPrintXMLFile{

public static void main (String argv []) throws ParserConfigurationException, SAXException, IOException{



try {

        DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
        Document doc = docBuilder.parse (new File("office.xml"));

        // normalize text representation
        doc.getDocumentElement ().normalize ();
        System.out.println ("Root element of the doc is " + 
        doc.getDocumentElement().getNodeName() + "\n");

        //counts how many times <name> is found in the file
        //then the number is used in the for loop below             
        NodeList listOfTerms = doc.getElementsByTagName("name");

        int totalTerms = listOfTerms.getLength();
        System.out.println("Total no of terms : " + totalTerms + "\n");



        for(int s= 0; s<listOfTerms.getLength() ; s++){


            Node firstTermNode = listOfTerms.item(s);
            if(firstTermNode.getNodeType() == Node.ELEMENT_NODE){


                Element firstTermElement = (Element)firstTermNode;

                //-------
                NodeList firstWordList = firstTermElement.getElementsByTagName("name");
                Element firstWordElement = (Element)firstWordList.item(0);

                NodeList textWordList = firstWordElement.getChildNodes();
                System.out.println("Name : " + 
                       ((Node)textWordList.item(0)).getNodeValue().trim());

                //-------
                NodeList defList = firstTermElement.getElementsByTagName("surname");
                Element defElement = (Element)defList.item(0);

                NodeList textDefList = defElement.getChildNodes();
                System.out.println("Surname : " + 
                       ((Node)textDefList.item(0)).getNodeValue().trim());



            }//end of if clause


        }//end of for loop with s var


    }catch (SAXParseException err) {
    System.out.println ("** Parsing error" + ", line " 
         + err.getLineNumber () + ", uri " + err.getSystemId ());
    System.out.println(" " + err.getMessage ());

    }catch (SAXException e) {
    Exception x = e.getException ();
    ((x == null) ? e : x).printStackTrace ();

    }catch (Throwable t) {
    t.printStackTrace ();
    }
    //System.exit (0);


}//end of main
}

Я получаю сообщение об ошибке:

java.lang.NullPointerException
    at Data.main(Data.java:45) //maybe a different line in the code for you.

Если я использую корень документа для счетчика, он печатает результат один раз, по какой-то причине getChildNodes () работает неправильно.

1 Ответ

2 голосов
/ 30 июня 2011

Я заметил, что вы делаете .getElementsByTagName ("name") дважды.Вы ожидаете теги в пределах ?Если нет, то это, скорее всего, причина вашей ошибки, поскольку во второй раз он вернет пустой список и вызовет исключение NullPointerException при попытке сослаться на firstWordElement

Вы не можете получить 'фамилию'из списка 'name', который вы делаете в цикле for.Получите их по отдельности, чтобы получить элементы name:

    NodeList listOfTerms = doc.getElementsByTagName("name");
    int totalTerms = listOfTerms.getLength();
    System.out.println("Total no of terms : " + totalTerms + "\n");
    for(int s= 0; s<listOfTerms.getLength() ; s++){
        Node firstTermNode = listOfTerms.item(s);
        if(firstTermNode.getNodeType() == Node.ELEMENT_NODE){
            Element firstTermElement = (Element)firstTermNode;
            System.out.println(firstTermElement.getTextContent());
        }//end of if clause
    }//end of for loop with s var

, а затем получить фамилию, просто измените тэг

listOfTerms = doc.getElementsByTagName("surname");
totalTerms = listOfTerms.getLength();
System.out.println("Total no of terms : " + totalTerms + "\n");
for(int s= 0; s<listOfTerms.getLength() ; s++){
    Node firstTermNode = listOfTerms.item(s);
    if(firstTermNode.getNodeType() == Node.ELEMENT_NODE){
        Element firstTermElement = (Element)firstTermNode;
        System.out.println(firstTermElement.getTextContent());
    }//end of if clause
}//end of for loop with s var

Надеюсь, что это поможет.

...