[XML+JAVA] XML parser veranderen na aanmaken

Pagina: 1
Acties:

  • Goldme
  • Registratie: September 2000
  • Laatst online: 21-08 13:42
Ik be op dit moment bezig met het maken van een applicatie die over sockets via XML communiceert. XML komt dus via een socket binnen.

Daarbij gebeurt het volgende:

code:
1
2
3
4
5
SAXParserFactory factory = SAXParserFactory.newInstance();
saxParser = factory.newSAXParser();
PreParser p= new PreParser(this);
inSource= new InputSource(new BufferedReader(new InputStreamReader(socket.getInputStream())));
            saxParser.parse(inSource, p);


De parser krijgt preparser mee als handler. Nu doet de preparser niks anders dan bepalen wat voor soort XML-bericht het is aan de hand van de eerste start-tag die hij tegenkomt, die info stuurt hij naar de hoofdprogramma op die zo bepaalt welke klasse hij zal aanmaken.

Aangezien de preparser niet nodig is na de eerste tag(identificatie) moet de parser alle volgende tags bij de nieuw aangemaakte handler melden, dat betekent dus dat er IN de parser de handler wordt veranderd. Er is echter geen methode hiervoor, ik kan de handler niet veranderen(met bijvoorbeeld saxParser.setcontenthandler(handler)). Met zo'n methode kan de parser rustig doorgaan met het rapporteren van tags en data maar nu aan een andere handler.

En als ik "saxParser.parse(insource,nieuwehandler)" na de preparse aanroep om de handler te veranderen ben ik bang dat de parser dus zo de start-document en de start-tag gemist heeft(die waren aan de preparser gemeld) en die xml-file dus niet meer kloppend is.

Heeft iemand een oplossing voor dit probleem?

Alvast bedankt.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Ik zoveel mogelijk met de SAX api werken en niet met de javax.xml.parsers.SAXParser. Als je kijkt naar de SAX api zie je dat je in feite met een XMLReader werkt. Deze heeft een methode setContentHandler.
Applications may register a new or different handler in the middle of a parse, and the SAX parser must begin using the new handler immediately.
Je kan aan een SAXParser de onderliggende XMLReader vragen.

Overigens zou je alle content ook kunnen 'forwarden' naar een andere ContentHandler. Qua design is dat best aardig. Je kan dan een ContentHandler kiezen naar aanleiding van je eerste element, waarna je daarna alles doorstuurt.

Je kan deze klasse extenden als je voor deze aanpak kiest:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

public abstract class ForwardContentHandler
    implements ContentHandler {

  protected ContentHandler _to;
    
  public ForwardContentHandler(ContentHandler to) {
    super();
    _to = to;
  }

  public void startDocument() throws SAXException {
    _to.startDocument();
  }
    
  public void endDocument() throws SAXException {
    _to.endDocument();
  }

  public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    _to.startElement(uri, localName, qName, attributes);
  }
      
  public void endElement(String uri, String localName, String qName) throws SAXException {
    _to.endElement(uri, localName, qName);
  }

  public void characters(char ch[], int start, int length) throws SAXException {
    _to.characters(ch, start, length);
  }
    
  public void setDocumentLocator(Locator locator) {
    _to.setDocumentLocator(locator);
  }

  public void startPrefixMapping(String prefix, String uri) throws SAXException {
    _to.startPrefixMapping(prefix, uri);
  }

  public void endPrefixMapping(String prefix) throws SAXException {
    _to.endPrefixMapping(prefix);
  }
      
  public void ignorableWhitespace(char ch[], int start, int length) throws SAXException {
    _to.ignorableWhitespace(ch, start, length);
  }
      
  public void processingInstruction(String target, String data) throws SAXException {
    _to.processingInstruction(target, data);
  }

  public void skippedEntity(String name) throws SAXException {
    _to.skippedEntity(name);
  }
}

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment