Probleme mit JDom . addContent(int index,Collection c)

polo85

Grünschnabel
Guten Tag,

ich sitze schon eine längere Weile an einem Problem und hoffe durch euch Hilfe zu bekommen.

Also folgendes Problem liegt vor:

Ich habe ein XML Dokument, dem eine unbestimmte Anzahl an Knoten hinzugefügt werden soll.

Bevor ich die Knoten jedoch hinzufüge muß, muß ich noch die richtige Position ermitteln.

Ich versuche nun das nötigste zum Verständnis meines (Verständis-)Problems darzustellen

zur Visualisierung:

ursprüngliche XML-Datei:
Code:
<article>
   <section>Eintrag a</section>
   <section>Eintrag c</section>
</article>

überarbeitete bzw.erwartete XML-Datei:

Code:
<article>
   <section>Eintrag a</section>
   <section>Eintrag b</section>
   <section>Eintrag bb</section>
   <section>Eintrag c</section>
   <section>Eintrag d</section>
</article>

Ich finde heraus das "Eintrag b" zwischen Eintrag a und Eintrag c gehört, also an die 2 <article> Stelle

Also rufe ich die Methode
Code:
doc.getRootElement().addContent(2,el);

Code:
<article>
    <section>Eintrag a</section>
    <section>Eintrag b</section>
    <section>Eintrag c</section>
</article>

auf. Wie erwartet erhalte ich auch das erwünschte Ergebnis und ich komme auf die Idee noch den Eintrag bb hinter Eintrag b einzufügen.
Also rufe ich erneut die Methode

Code:
doc.getRootElement().addContent(3,el);

Code:
<article>
   <section>Eintrag a</section>
   <section>Eintrag b</section>
   <section>Eintrag bb</section>
   <section>Eintrag c</section>
</article>

auf und es klappt erneut.

So zu letzt versuche ich den Eintrag d an die 5 Stelle hinzufügen:

Code:
doc.getRootElement().addContent(5,el);

Code:
<article>
      <section>Eintrag a</section>
      <section>Eintrag b</section>
      <section>Eintrag bb</section>
      <section>Eintrag d</section>
      <section>Eintrag c</section>
</article>

Nun stellt sich mit die Frage warum ich
Code:
doc.getRootElement().addContent(6,el)

aufrufen muß um mein erwünschtes Ergebnis zu erhalten.

Ich hoffe ich habe mein Prob nicht all zu umständlich erklärt.
Ich bin ich dabei einen Automatismus einzubauen der über eine Iteration dynamisch die richtige Stelle im Xml Dokument erkennt und den Eintrag an die richtige Stelle schreibt, wobei mir noch der richtige Algorithmus fehlt.

in etwa so :


Code:
for (int i = 0; i < anzahlEinträge; i++)
{
   if(neuerEintragGehoertAnDieseStelle)
   {
      intOrt = i + (?) )); 
      break;
   }
}

doc.getRootElement().addContent(intOrt,el);



Viele Grüße
und Danke im Voraus für eure Bereitschaft zu Helfen

Polo85
 
Hallo!

Also ich habe nun einen guten Lösungsansatz für mein Problem gefunden.
Ihr könnt mich gerne noch Tipps geben, aber ich denke dieser Ansatz ist Ok.

Ich gehe nun davon aus das bereits das XML-Dok wie folgt aussieht:

Code:
<article>
      <section>Eintrag a</section>
      <section>Eintrag b</section>
      <section>Eintrag bb</section>
      <section>Eintrag c</section>
</article>

Als erstes hole ich mir alle children vom root.
Iteriere solange über die children bis meine Bedingung erfüllt ist, hole mir mit der magischen Methode, die ich bisher nicht kannte, indexOf() den Inhalt des Childs das vor meinem neuen Eintrag kommt und addiere den mit eins damit sich der neue Eintrag hinten anfügt.

Code:
Iterator<Element> children = doc.getRootElement().getChildren().iterator();
Element elm = null;
int idx = 0;
		
while (children.hasNext())
{
   elm = children.next();
   idx++;
   if (elm != null)
   {
       if (elm.getText().equals("Eintrag c"))
       {
	      idx = doc.getRootElement().indexOf(elm);
	      doc.getRootElement().addContent(idx + 1, new Element("section").addContent("Eintrag d"));
	      break;
        }
    }
}

Solltet ihr noch bessere Lösungsmöglichkeiten haben, so postet bitte herein.

Viele Grüße Polo85
 
Zuletzt bearbeitet:
Hallo,

mich wundert gerade ehrlich gesagt das es so klappt.

Denn eigentlich beginnt die Zählung von Listen bei 0. Wenn Du also nen Element an Stelle 2 einfügst, dann wäre es an 3 Stelle in der Liste. Also müßte Deine Liste eigentlich a, c, b sein, wenn Du b einfügst und nicht wie bei Dir a, b, c.

Wenn Du weißt, dass das Element das Du anfügst auf jeden Fall das letzte Deiner Liste ist, dann reicht auch einfach nur add(elemen); aus.

Gruß KlaDi.
 
Und genau das ist es auch was mich verwundert hat und ich zähneknirschend akzeptieren mußte ich weiß nicht wie die Jungs von JDom die Child durchnummerieren, auf alle Fälle anders wie wir beide annehmen, du kannst dir ja den Index eines jeweiligen Elements per indexOf() anzeigen lassen und du wirst erkennen, dass nicht normal durchnummeriert wird.
Vielleicht weiß ja jemand anderes genaueres ...grüße
 
Hallo,

also ich hab auch mir JDOM gearbeitet. War mir aber dann zu umständlich und unkomfortabel, deshalb bin ich auf JAXB umgestiegen, aber das ist ein anderes Thema.

Auf jeden Fall war es bei mir so das auch JDOM die Zählung bei 0 begonnen hat. Kann aber auch sein das in einer neueren/älteren Version als die ich benutzt habe ein Bug ist!?

Gruß KlaDi.

PS: Hast Du es mal probiert, wenn Du einfach davon ausgehst das die Zählung bei 0 beginnt, also add(1, "b") statt add(2, "b")?
 
Ich finde JDom keineswegs umständlich oder unkomfortabel, aber ich hatte auch mal das Vergnügen mit JAXP zu arbeiten, jedoch war ich damit nicht wirklich zufrieden ...Es ist also eine Gewohnheitssache.

Um auf die Durchnummerierung bei JDom Elemente zurückzukommen:

Das einfügen des "Eintrag d" meines vorletzten Beitrags

an der Stelle

addContent(0,el) oder addContent(1,el) bewirken das hinzufügen von "Eintrag d" an erster Position.

addContent(2,el) oder addContent(3,el) an zweiter Position.

addContent(4,el) oder addContent(5,el) an dritter Position.

addContent(6,el) oder addContent(7,el) an vierter Position.

addContent(8,el) oder addContent(9,el) an letzer Position.

erst der Aufruf mit addContent(10,el)

löst nachfolgende Exception aus:

Code:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 10 Size: 9
	at org.jdom.ContentList.add(ContentList.java:237)
	at org.jdom.Element.addContent(Element.java:840)
	at jdom.DescendantDemo.main(DescendantDemo.java:169)



Viele Grüße Polo
 
Hmm, der Fehler ist klar, wenn die size nur 9 ist, dann wird von 0 - 8 nummierert und an Stelle 10 kann nicht eingefügt werden, weil es 9 nicht gibt.

Und JAXP ist nicht JAXB.

Gruß KlaDi.
 
Dann schau ich mir mal JAXB genauer an, vielleicht überzeugt es mich ja auch...

Wegen der Nummerierung wundert mich eben, dass es überhaupt bis 9 geht, bei nur 4 childs von <article>.

grüße
 
Mach das.

Es ist halt sehr schön damit zu arbeiten. Weil Du Dir einfach ein XML-Schema erstellst. Dann lässt Du Dir daraus die Klassen generieren und bekommst diese mit Getter und Setter-Methoden.

Gruß KlaDi.
 
Dieser Post ist schon etwas älter, denoch lohnt sich hier noch eine Antworten.

Ich habe einen kleinen Artikel verfasst Tutorial JAXB mit Eclipse

Dieser Artikel erklärt wie Du relativ einfach aus XML -> Java Klassen erzeugen kannst. Als Framework dient Eclipse mit dem genialen Plugin: XJC Eclipse Plugin.

In einem folgenden Artikel geht es um den Einsatz der erzeugten JAXB Klassen: Tutorial JAXB with Eclipse: In the Runtime

Hoffe das Hilft für einen sanften Einstieg in die Welt von JAXB******
 
Zurück