[Java/XML] Het lezen van dynamische namen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Gynnad
  • Registratie: September 2010
  • Laatst online: 16:18
Hallo,

Ik zit met een probleem, het lukt me gewoon goed om XML uit te lezen, nu zit ik alleen met 1 probleem, het stukje XML wat ik moet uitlezen heeft een dynamische naam (als dat het goede woord is).

Hij veranderd namelijk de heletijd van naam, het ziet er als volgt uit:

XML:
1
2
3
4
5
6
7
8
<event id="14">
<week9 score="946">959.52</week9>
<week8 score="902">977.62</week8>
<week7 score="925">968.19</week7>
<week6 score="920">970.17</week6>
<week5 score="916">971.88</week5>
<trainingWeek>9</trainingWeek>
</event>


Maar een week later ziet het er zo uit:

XML:
1
2
3
4
5
6
7
8
<event id="14">
<week10 score="978">952.52</week10>
<week9 score="946">959.52</week9>
<week8 score="902">977.62</week8>
<week7 score="925">968.19</week7>
<week6 score="920">970.17</week6>
<trainingWeek>9</trainingWeek>
</event>


Hoe kun je dit het beste doen? Mijn code ziet er nu als volgt uit:
code:
1
2
3
4
5
6
7
8
            for (Event e : wt.getEventsWeeklyTest()) {
                for (Week w : e.getWeeksEvent()) {
                    week = new Week(w.getScoreEvent());
                    weeks.add(w);
                }
                event = new Event(1, weeks);
                events.add(e);
            }


En in de domain klasse als volgt bij event waar het dus verkeerd gaat:
code:
1
2
  @XmlElement(name="week") //deze week zou eigenlijk dynamisch moeten zijn
   ArrayList<Week> weeks;

[ Voor 0% gewijzigd door BtM909 op 03-02-2012 16:39 ]

"Don't worry, about a thing, Cause every little thing is gonna be alright"


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Tsja, de bron is gewoon een verkeerde manier van xml gebruiken, dus het beste wordt die veranderd. Met een SAX-parser hoeft het inlezen niet zo'n groot probleem te zijn.

[ Voor 7% gewijzigd door pedorus op 03-02-2012 15:15 ]

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Met pedorus: als het in de bron te fixen is, dan is dat veruit de beste oplossing.

Met annotaties ga je er anders niet komen, die zijn niet dynamisch.

"Any sufficiently advanced technology is indistinguishable from magic."


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Of natuurlijk gewoon een DOM parser als de documenten niet te groot zijn, dat kan op zich wat fijner werken.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Gynnad
  • Registratie: September 2010
  • Laatst online: 16:18
pedorus schreef op vrijdag 03 februari 2012 @ 15:14:
Tsja, de bron is gewoon een verkeerde manier van xml gebruiken, dus het beste wordt die veranderd. Met een SAX-parser hoeft het inlezen niet zo'n groot probleem te zijn.
Zal daar eens contact meeopnemen, want ik vind het ook maar vreemd.

Beter zou zijn:
code:
1
2
3
4
5
6
7
8
<event id="14">
<week weeknr="10" score="978">952.52</week>
<week weeknr="9" score="946">959.52</week>
<week weeknr="8" score="902">977.62</week>
<week weeknr="7" score="925">968.19</week>
<week weeknr="6" score="920">970.17</week>
<trainingWeek>10</trainingWeek>
</event>

"Don't worry, about a thing, Cause every little thing is gonna be alright"


Acties:
  • 0 Henk 'm!

  • YopY
  • Registratie: September 2003
  • Laatst online: 13-07 01:14
Ja precies: week is een variabele, die encode je niet in je XML.

...Oke, in het geval van weken zit je wel met een limiet (week1 t/m week52, om maar even grof en waarschijnlijk incorrect te zijn), maar het blijft een verkeerde datastructuur.

Acties:
  • 0 Henk 'm!

  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 20-09 00:06
Je hoeft niet helemaal JAXB uit het raam te gooien als dit het enige stukje van een groter XML is dat problemen geeft, bijvoorbeeld:
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
public class Event {
    @XmlAttribute
    public int id;
    
    @XmlElement
    private int trainingWeek;
    
    @XmlAnyElement
    @XmlJavaTypeAdapter(WeekAdapter.class)
    private List<Week> weeks = new ArrayList<Week>();
}

public class WeekAdapter extends XmlAdapter<Element, Week> {
    @Override
    public Week unmarshal(Element el) throws Exception {
        Week w = new Week();
        w.setWeeknr(Integer.parseInt(el.getNodeName().substring(4)));
        w.setScore(Integer.parseInt(el.getAttribute("score")));
        w.setValue(Double.parseDouble(el.getTextContent()));
        return w;
    }

    @Override
    public Element marshal(Week bt) throws Exception {
        throw new UnsupportedOperationException();
    }
}

Acties:
  • 0 Henk 'm!

  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 02:50
Pas heel erg goed op het het parsen van dit soort "xml" structuren met de default parser settings in Java.
De standaard JAXP Xerces parser zal namelijk een String#intern() aanroepen voor alle element en attribuut namen in het document. Deze String objecten worden daardoor voor de volledige lifecycle van de JVM in de String contant pool bewaard. Als je dus grote structuren met steeds veranderende naamgeving regelmatig inleest, dan ben je op een gegeven moment door je permgen heen.

Acties:
  • 0 Henk 'm!

  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 20-09 00:06
FallenAngel666 schreef op vrijdag 03 februari 2012 @ 20:59:
Pas heel erg goed op het het parsen van dit soort "xml" structuren met de default parser settings in Java.
De standaard JAXP Xerces parser zal namelijk een String#intern() aanroepen voor alle element en attribuut namen in het document. Deze String objecten worden daardoor voor de volledige lifecycle van de JVM in de String contant pool bewaard. Als je dus grote structuren met steeds veranderende naamgeving regelmatig inleest, dan ben je op een gegeven moment door je permgen heen.
Sinds JDK 1.2 zijn interned Strings weak references en kunnen worden ge-gc'd. Daarnaast gaat het hier over 52 verschillende elementen, wel meerdere ordes van groottes voordat dit een probleem zou worden. Maar het is inderdaad ook een goede reden om niet dynamische element namen te gebruiken als je opeens op het idee zou komen om <element1> t/m <element100000> te gebruiken ;)

Acties:
  • 0 Henk 'm!

  • Macros
  • Registratie: Februari 2000
  • Laatst online: 15-05 16:29

Macros

I'm watching...

matthijsln schreef op vrijdag 03 februari 2012 @ 17:02:
Je hoeft niet helemaal JAXB uit het raam te gooien als dit het enige stukje van een groter XML is dat problemen geeft, bijvoorbeeld:
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
public class Event {
    @XmlAttribute
    public int id;
    
    @XmlElement
    private int trainingWeek;
    
    @XmlAnyElement
    @XmlJavaTypeAdapter(WeekAdapter.class)
    private List<Week> weeks = new ArrayList<Week>();
}

public class WeekAdapter extends XmlAdapter<Element, Week> {
    @Override
    public Week unmarshal(Element el) throws Exception {
        Week w = new Week();
        w.setWeeknr(Integer.parseInt(el.getNodeName().substring(4)));
        w.setScore(Integer.parseInt(el.getAttribute("score")));
        w.setValue(Double.parseDouble(el.getTextContent()));
        return w;
    }

    @Override
    public Element marshal(Week bt) throws Exception {
        throw new UnsupportedOperationException();
    }
}
Dat is trouwens best coole sh*t!

"Beauty is the ultimate defence against complexity." David Gelernter


Acties:
  • 0 Henk 'm!

  • Gynnad
  • Registratie: September 2010
  • Laatst online: 16:18
matthijsln schreef op vrijdag 03 februari 2012 @ 17:02:
Je hoeft niet helemaal JAXB uit het raam te gooien als dit het enige stukje van een groter XML is dat problemen geeft, bijvoorbeeld:
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
public class Event {
    @XmlAttribute
    public int id;
    
    @XmlElement
    private int trainingWeek;
    
    @XmlAnyElement
    @XmlJavaTypeAdapter(WeekAdapter.class)
    private List<Week> weeks = new ArrayList<Week>();
}

public class WeekAdapter extends XmlAdapter<Element, Week> {
    @Override
    public Week unmarshal(Element el) throws Exception {
        Week w = new Week();
        w.setWeeknr(Integer.parseInt(el.getNodeName().substring(4)));
        w.setScore(Integer.parseInt(el.getAttribute("score")));
        w.setValue(Double.parseDouble(el.getTextContent()));
        return w;
    }

    @Override
    public Element marshal(Week bt) throws Exception {
        throw new UnsupportedOperationException();
    }
}
Inderdaad toffe code en werkt als een tierelier! Bedankt :)

Maar hoe kom je hier aan, waar zoek je dan precies op, want ik ben hier dus niet bij gekomen..

"Don't worry, about a thing, Cause every little thing is gonna be alright"


Acties:
  • 0 Henk 'm!

  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 20-09 00:06
Gynnad schreef op maandag 06 februari 2012 @ 14:01:
[...]
Inderdaad toffe code en werkt als een tierelier! Bedankt :)

Maar hoe kom je hier aan, waar zoek je dan precies op, want ik ben hier dus niet bij gekomen..
Mooi :) Ik wist wel dat @XmlAnyElement bestond, maar de combinatie met de XmlJavaTypeConverter was eigenlijk een probeerseltje wat meteen goed werkte. Op Internet deze exacte combi niet gevonden, maar op zich wel logisch dat het zo werkt. De XmlAdapter converteert tussen de representatie in je object graph (Week) en hoe deze gemarshalled/unmarshalled moeten worden (org.w3c.dom.Element). In voorbeelden van XmlAdapter zie je voor de marshalling representatie meestal gewone beans met JAXB annotaties, maar door XmlAnyElement worden dit dus DOM elementen.
Pagina: 1