Toon posts:

[java/xml]generiek results verwerken

Pagina: 1
Acties:

Verwijderd

Topicstarter
Zoals te lezen is in dit [rml][ java/xml]pattern voor afhandelen XML[/rml] topic, ben ik ben bezig met het maken van een generieke xml reader.Even in het kort: Ik laat tags afhandelen doormiddel van reflection, dus voor elke tag is er een corresponderende klasse.

Beschouw het volgende stukje xml:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<dbms-servers>
    <server name="MYSQL">
        <driver>org.gjt.mm.mysql.Driver</driver>        
        <data-types>
            <data-type type="TEXT">TEXT</data-type>
            <data-type type="VARCHAR">VARCHAR</data-type>
            <data-type type="INTEGER">INTEGER</data-type>           
        </data-types>
    </server>
    <server name="MSSQL">
        <driver>org.ms.whatever.Driver</driver>
        <data-types>
            <data-type type="TEXT">TEXT</data-type>
            <data-type type="VARCHAR">VARCHAR</data-type>
            <data-type type="INTEGER">INTEGER</data-type>           
        </data-types>
    </server>
</dbms-servers>

Zoals je ziet worden in dit bestand verschillende servers beschreven. Nu wil ik dat bijvoorbeeld de tag "<server>" zijn informatie naar een bepaalde klasse schrijft (die dan per direct afgehandeld word en verwijderd wordt), de volgende keer dat een "server" tag gevonden wordt dient uiteraard weer hetzelfde te gebeuren. Dit alles moet generiek zijn dus elke mogelijk situatie aankunnen.

Ik zat zelf te denken aan het volgende:
code:
1
2
3
4
5
6
7
//een functie uit de tag handler interface
public Properties startElement(ResultHandler handler,
                           Properties properties
                           String uri,
                           String localName,
                           String qName,
                           Attributes attributes);

Oftewel elke functie returned de megeleverde properties en voegt er eventueel iets aan toe. Bij de tag-invoker zorg ik er dan voor dat diezelfde properties steeds met elke teg handler worden meegeleverd. Een sluit element van bijvoorbeeld "server" zou dan de properties kunnen verwerken, en een null returnen. Het start element zou dan een nieuwe properties kunnen aanmaken.

De interface ResultHandler zou dan een methode processProperties o.i.d. moeten hebben zodat een volledig gevulde properties instantie afgehandeld kan worden.

Toch vind ik het een beetje omslachtig, dus ik vroeg me af of er betere manieren zijn (ongetwijfeld).

ps.
Ik wil niet met een of andere DOM implementatie werken, dit vanwege resources...

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
(beetje algemeen geblaat)

Je zal toch ergens op een specifieke situatie over moeten stappen: de DOM is juist de generieke representatie van een XML document en je kent het resultaat van zo'n generieke aanpak.

XML inlezen is in het algemeen nog steeds een groot probleem. SAX & DOM zijn veel te low-level, maar zeker als je strenge performance eisen stelt zal je er toch snel gebruik van moeten maken. XML data binding oplossen zijn vaak inefficient (omdat ze een DOM gebruiken die onmiddelijk garbage is) of inflexibel (waardoor het XML formaat erg veel op een klasse structuur begint te lijken of de klasse structuur erg veel op de XML).

Op dit moment zijn er dus eigenlijk nog geen oplossingen waar je je echt lekker bij voelt (althans, ik in ieder geval niet ;) ).

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


Verwijderd

Topicstarter
Dat idee had ik inderdaad ook al, vandaar dat ik hier maar is voor expertise kom aankloppen :). Nu ik verder aan het modelleren ben zit ik te denken om bij elke methode Alleen een ResultHandler interface aan te bieden. Dus per type xml bestand zal je dus een apparte klasse moeten schrijven om het resultaat te verwerken. In deze interface zit ik te denken aan de volgende methodes:
code:
1
2
3
4
5
6
7
8
9
10
//een nieuwe set voor het opslaan van een deel van het xml bestand
//en zet de set op default voor de addfuncties
//returns false als er als de set al bestaat
public boolean createSet(String id);

public void processSet()
//of
public void processSet(SetHandler setHandler);

public void add(...) //voor het toevoegen bla die bla

Verwijderd

Misschien vergis ik me maar ik hen het idee dat Sun daar al iets voor heeft gemaakt. Ik weet niet of je hier al naar gekeken hebt maar Java Architecture for XML Binding (JAXB) lijkt mij precies wat jij probeert te maken. Hiermee definieer je ook voor elke XML tag een class die die tag afhandelt.

edit:
Oops ik zie in een vorige reply dat je XML data binding oplossingen al te inefficient vindt. In dat geval heb ik niets gezegd :X :)

[ Voor 37% gewijzigd door Verwijderd op 26-02-2003 13:50 ]


Verwijderd

Is niet echt een generieke oplossing, dus niet echt een antwoord op je vraag, maar je zou ook eens moeten kijken of je niet een combinatie van DOM en SAX kunt gebruiken. Als je zulke grote documenten hebt zal 9 vd 10 keer dit komen doordat je XML document erg lang is en niet door de diepte. In je voorbeeld XML file zou je bijvoorbeeld elke server knoop afzonderlijk best als DOM kunnen parsen. (en qua geheugengebruik moet dat prima kunnen aangezien je huidige doel ook is om diezelfde gegevens bij elkaar in het geheugen te krijgen (in een klasse)).

Verwijderd

Topicstarter
hondass50:
Uiteraard ontkom je er niet aan om hier en daar iets te bufferen, maar ik wil dus eigelijk de boom proberen te vermijden. Als ik daar eenmaal aan begin doe ik immers dubbel werk, ik interpreteer nu domweg per tag met een custimized tagClass. Alleen de terugkoppeling naar een klasse waar de data dan verwerkt wordt mis ik nog.

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 03:34

GrimaceODespair

eens een tettenman, altijd ...

In .NET wordt de XML Definitie gebruikt om klasses te generen van het type dat jij nu bescchrijft. Ik weet niet of het je veel helpt, maar je zou daar es een kijkje kunnen nemen. Je moet dan wel het XML schema hebben van de XML die binnenkomt, zodat die klasses van tevoren gegenereerd kunnen worden. Of is het per se nodig dat dat on-the-fly gebeurt?

Wij onderbreken deze thread voor reclame:
http://kalders.be


Verwijderd

Topicstarter
Klinkt als een DTD? Als dat zo is dan hoef ik me daar geeen zorgen over te maken want dat doet SAX al voor mij. Het is inderdaad nodig dat het on the fly gebeurd. Er moeten errug grote bestanden verwerkt kunnen worden.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Deze aanpak wordt dus ook wel XML data binding genoemd. Dit hoeft niet direct te betekenen dat er een DOM gebruikt wordt. Wellicht wordt er in .NET Pull gebruikt en is de performance daar dus ook bij grotere XML bestanden aardig.

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

Pagina: 1