Avatar billede bris Nybegynder
23. juni 2003 - 14:46 Der er 8 kommentarer og
1 løsning

Skod SAXParser!!

Jeg kæmper for vildt med et monster xml-dokument, og bruger en SAXParser til det!
Jeg har implmenteret en DefaultHandler, og det er den som giver mig problemer. Det er ligesom at metoden Characters(..) giver mig falske informationer.. Den er implementeret sådan, og det char-array den har swapper på når den kommer over 8000 char, og så smider den nogle af mine data væk..
Måske er fejlen min, for jeg har prøvet både xerces og den der ligger i org.xml, og begge giver mig falske data..
Nogen der kan se hvad jeg gør galt?

private PreparedStatement ps;
  private DatabaseHandler dbhandler;
  private String currentType;
  private boolean inLine;
  private String tablename;
  private String currentElement;
  private String currentValue;


public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

    currentElement = localName;
    if (localName.equals(tablename)) {
      line = new ArrayList();
      inLine = true;
    }

    if ((!currentElement.equals(tablename)) && (attributes.getLength() > 0)) {
      currentType = attributes.getValue("type");
    }


  }


public void characters(char[] ch, int start, int length) throws SAXException {


    if (inLine && !currentElement.equals(tablename)) {
      String value = new String(ch, start, length);
      currentValue = value;
    }


  }

public void endElement(String uri, String localName, String qName) throws SAXException {


    if ((!qName.equals(tablename)) && (!qName.equals("Table"))) {

      Node attr = new Node(currentElement, currentValue, currentType);
      line.add(attr);

    }

    if (qName.equals(tablename)) {
      inLine = false;
      if (ps == null) {

        String prepared = makePreparedStatement(tablename, line);
        ps = dbhandler.prepareStatement(prepared);
      }
            ImportDatabaseHandler.handleLine(tablename, line, ps);
            line = null;

    }

    if (qName.equals("Table")) {
    try {
        if (ps != null) {
          ps.close();
        }
      }
      catch (SQLException sqe) {
        sqe.printStackTrace();
      }
    }

  }


ps.. Jeg ved godt at det ikke ligner en rigtig .java fil, men nok til en forståelse håber jeg.. :)
Avatar billede arne_v Ekspert
23. juni 2003 - 15:03 #1
Prøv og lav currentvalue om til en StringBuffer, append til den
i characters og nulstil passende.
Avatar billede arne_v Ekspert
23. juni 2003 - 15:03 #2
Fordi characters kan godt blive kaldt multiple gange for
tekst mellem start tag og end tag.
Avatar billede arne_v Ekspert
23. juni 2003 - 15:05 #3
Kode fragment:

    private StringBuffer element = new StringBuffer();
...
    public void characters(char buf[], int offset, int len)
        throws SAXException {
        element.append(new String(buf, offset, len));
        return;
    }

    public void startElement(
        String namespaceURI,
        String localName,
        String rawName,
        Attributes atts)
        throws SAXException {
...
            element = new StringBuffer();
...
        return;
    }
    public void endElement(
        String namespaceURI,
        String localName,
        String rawName)
        throws SAXException {
// brug element.toString()
        return;
    }
}
class Element {
    private int nbr;
    private String name;
    private boolean include;
    public Element() {
        nbr = 0;
        name = null;
        include = false;
    }
    public Element(int nbr, String name, boolean include) {
        this.nbr = nbr;
        this.name = name;
        this.include = include;
    }
    public int getNbr() {
        return nbr;
    }
    public String getName() {
        return name;
    }
    public boolean isInclude() {
        return include;
    }
    public void setNbr(int nbr) {
        this.nbr = nbr;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setInclude(boolean b) {
        include = b;
    }
    public String toString() {
        return ("[" + nbr + "," + name + "," + include + "]");
    }
}
Avatar billede arne_v Ekspert
23. juni 2003 - 15:06 #4
Hov - ignorerer lige alt efter endElement metode - resten skulle også
have været slettet - det har ikek noget med sagen at gøre.
Avatar billede bris Nybegynder
23. juni 2003 - 15:09 #5
Hvad mener du præcis? noget lignende:

for(int i = start; i < length; i++) {
  buffer.append(ch[i]);
}

eller tænkte du på noget andet?
Avatar billede bris Nybegynder
23. juni 2003 - 15:10 #6
ahh.. okay.. Jeg havde ikke set den sidste post.. tester lige!!
Avatar billede bris Nybegynder
23. juni 2003 - 15:21 #7
Arne.. Du er fandme genial! Hvordan er det lige, at man skal kunne vide det? Point velfortjent!! Takker!!
Avatar billede tobiashm Nybegynder
23. juni 2003 - 16:54 #8
At character handleren kan kaldes flere gange? Det står i beskrivelsen af sax ;-)
Avatar billede arne_v Ekspert
23. juni 2003 - 18:08 #9
Det er faktisk ikke helt nemt at finde.

DefaultHandler overview og ContentHandler overview siger bare:

void characters(char[] ch, int start, int length)
Receive notification of character data inside an element.

DefaultHandler details siger også kun:

public void characters(char[] ch,
                      int start,
                      int length) throws SAXException

Receive notification of character data inside an element.

By default, do nothing. Application writers may override this method to
take specific actions for each chunk of character data (such as adding the
data to a node or buffer, or printing it to a file).

Specified by:
characters in interface ContentHandler

Parameters:
ch - The characters.
start - The start position in the character array.
length - The number of characters to use from the character array.
Throws:
SAXException - Any SAX exception, possibly wrapping another exception.
See Also:
ContentHandler.characters(char[], int, int)

Først ContentHandler details siger:

public void characters(char[] ch,
                      int start,
                      int length) throws SAXException

Receive notification of character data.

The Parser will call this method to report each chunk of character data. SAX
parsers may return all contiguous character data in a single chunk, or they
may split it into several chunks; however, all of the characters in any single
event must come from the same external entity so that the Locator provides
useful information.

The application must not attempt to read from the array outside of the specified range.

Note that some parsers will report whitespace in element content using the
ignorableWhitespace method rather than this one (validating parsers must do
so).

Parameters:
ch - The characters from the XML document.
start - The start position in the array.
length - The number of characters to read from the array.
Throws:
SAXException - Any SAX exception, possibly wrapping another exception.
See Also:
ignorableWhitespace(char[], int, int), Locator

og det er altså først der man får det at vide.
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