Avatar billede benjams69 Nybegynder
07. marts 2011 - 21:15 Der er 11 kommentarer og
1 løsning

Parsing af XML med SAX - klasse returnerer 'null'

Hej Eksperten,
Jeg har et større problem i forbindelse med parsing af en XML-fil og "manupulering" af nodes værdier.

Lavpraktisk har jeg en XML-fil med nogle tags (something.xml):

=================================================

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <phrase id="1" value="something"/>
    <phrase id="2" value="different"/>
</data>

=================================================

min klasse ser således ud:

=================================================

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;


public class Parser extends DefaultHandler{
   
    private String id, value, something, different;
    private String xmlfile = "something.xml";
    int index;
   
    public Parser(){
    }
   
    public void parseDocument(){
        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            DefaultHandler handler = new Language();
            parser.parse(xmlfile, handler);
        }
        catch (Exception e) {
        }
    }
    // start element
    public void startElement(String uri, String localName, String qname, Attributes atts) throws SAXException {
        if(qname.equals("phrase")){
            id = atts.getValue("id");
            value = atts.getValue("value");
        }
        index = Integer.valueOf(id);
    }
    // end element
    public void endElement(String uri, String localName, String qname) throws SAXException{
        doStuff(index, value);
    }
    // switch case manipulation
    public void doStuff(int i, String s){

        switch(i){
        case 1: setSomething(s); break;
        case 2: setDifferent(s); break;
        default: System.out.println("Oh noes!");
       
        }
    }
   
    public void setSomething(String s){
        something = s;
    }
   
    public void setDifferent(String s){
        different = s;
    }
   
    public String getSomething(){
        return something;
    }
   
    public String getDifferent(){
        return different;
    }
}

=================================================

Testklassen:

=================================================

public class ParserTest {

    public static void main(String[] args) {
        Parser p = new Parser();
        p.parseDocument();
       
        System.out.printf("%s %s", p.getSomething(), p.getSomething());
    }
}


I stedet for at udskrive "something different", får jeg blot "null null".
Hvis jeg mens xml-filen parses udskriver værdier er der ingen problemer. Det udskrives det rigtige...

Nogle ideer til hvordan jeg kommer videre?
Avatar billede arne_v Ekspert
07. marts 2011 - 21:38 #1
Skulle:

            DefaultHandler handler = new Language();
            parser.parse(xmlfile, handler);

have vaeret:

            parser.parse(xmlfile, this);

?
Avatar billede arne_v Ekspert
07. marts 2011 - 21:39 #2
PS: medmindre din XML fil er meget stor, saa vil jeg nok anbefale DOM og XPath til at hive data ud med.
Avatar billede benjams69 Nybegynder
07. marts 2011 - 22:15 #3
Hov ja, det er sjusket copy / paste fra min side af. Det skulle have været

DefaultHandler handler = new Parser();
parser.parse(xmlfile, handler);

men man kunne også bare nøjes med at skrive parser.parse(xmlfile, this);

Jeg har også kigget på DOM, men nu er jeg blevet stædig! Også fordi xml-filen kan gå hen og blive relativ stor (sprogfil i sidste ende)
Avatar billede benjams69 Nybegynder
07. marts 2011 - 22:31 #4
Alright, fejlen er fundet :)

Udover at
DefaultHandler handler = new Parser();
parser.parse(xmlfile, handler);

skulle være
parser.parse(xmlfile, this);

skulle
index = Integer.valueOf(id);

én linje højere op... Hvis du kaster et svar får du point for hjælpen :)
Avatar billede arne_v Ekspert
07. marts 2011 - 22:34 #5
DefaultHandler handler = new Parser();
parser.parse(xmlfile, handler);

duer ikke fordi du saa gemmer i et andet Parser objekt end det du henter fra.

Brug:

parser.parse(xmlfile, this);
Avatar billede arne_v Ekspert
07. marts 2011 - 22:34 #6
og naar du saa erstatter:

        catch (Exception e) {
        }

med:

        catch (Exception e) {
            e.printStackTrace();
        }

kan du se hvor det gaar galt.
Avatar billede arne_v Ekspert
07. marts 2011 - 22:35 #7
public void startElement(String uri, String localName, String qname, Attributes atts) throws SAXException {
        if(qname.equals("phrase")){
            id = atts.getValue("id");
            value = atts.getValue("value");
        }
        index = Integer.valueOf(id); // <------- skal flyttes ind i if !!
    }
Avatar billede arne_v Ekspert
07. marts 2011 - 22:35 #8
svar
Avatar billede arne_v Ekspert
07. marts 2011 - 22:36 #9
stor XML fil er stoerre end 10 MB !
Avatar billede benjams69 Nybegynder
07. marts 2011 - 22:38 #10
10mb rammer jeg næppe - men nu er jeg også blevet dét klogere på SAX :)
Avatar billede arne_v Ekspert
07. marts 2011 - 22:45 #11
Problemet med DOM er memory forbrug.

Regn med at en XML fil indlaest i DOM fylder 4-5 gange saa meget som paa disk.

10 MB bliver til 40-50 MB i memory.

Det er ikke noget problem paa idags computere.

Og at hente ud med XPath er altsaa noget nemmere.
Avatar billede benjams69 Nybegynder
07. marts 2011 - 23:01 #12
Jeg har bestemt ikke tænkt mig kun at bruge SAX for fremtiden - bruger også DOM i andre sammenhænge.

Men igen, jeg har lært lidt :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester