JDOM - letztem Child Attribut hinzufügen

ninakind

Grünschnabel
Hallo Allerseits,

ich steh gerade total auf dem Schlauch und bin wieder etwas aus JDOM raus...

Mein Problem ist folgendes. Ich habe eine XML-Datei, bei der ich dem allerletzten child ein weiteres Attribut hinzufügen will. Ich weiß anfangs nicht, wie tief dieses child geschachtelt ist. Hier mal ein Auszug aus einer möglichen Datei:

Code:
<RULESET>
   <RULE S="NP" EXCEP="1">
      <node cat="NP"
         <word pos="Pgen" />   
          <node cat="PPgen">
               <word pos="VN" /> 
          </node>
      </node>
   </RULE>
</RULESET>

Hier soll nun dem letzten Element "word" (mit pos=VN) ein weiteres Attribut "form=bla" hinzugefügt werden. Bisher hab ich immer direkt auf ein child zugegriffen, aber wenn ich ja nicht weiß, was alles für Knoten vorangehen, klappt das ja nicht, oder?

Hier ein Auszug, wie ich bisher auf z.B. das erste word zugegriffen hab:

Code:
Element root = doc.getRootElement();    
 Element word = root.getChild( "RULE" ).getChild( "word" );
 word.setAttribute("form", literal_found);

Schon mal vielen Dank für Ideen und Vorschläge, wie das klappen soll.:)
 
Howdie.

Prinzipiell würde ich mir mal anschauen, was JDOM mit XPath so anstellen kann. Das ist glaube ich relativ mächtig.
Ansonsten bleibt immer noch der Weg mit einer Rekursion, die durch die Knoten geht und die Verschachtelungs-Tiefen vergleicht. So würde ich es jedenfalls machen.
Falls du damit noch Hilfe brauchen solltest (ggf. niemand hat eine bessere Idee), melde dich einfach.

Gruß
miffi
 
Danke erst mal für die Antwort ^_^

Hm, ich werd mich mal gleich ans Ausprobieren machen. Das mit Xpath könnte wohl noch eine gute Idee sein - ich bin nur unsicher, ob das auch so einfach klappen soll.
Ich könnte das gesamte Dok einlesen und dann nach Abfrage, wie viele Knoten drin sind, so irgendwie auf das letzte zugreifen. Die Frage ist nur, kann ich das Element dann als Teil des gesamten Doks abändern und speichern? Oder klappt es nur, das einzelne Element zu speichern? Hm, ich grübel einfach mal ein bisschen weiter und werd nachher ein paar Testläufe starten. Ansonsten probier ich die rekursive Lösung.
 
Also erstmal eine Richtigstellung:
Du ziehst mit dem Aufruf der SAXBuilder#build(...) Methode IMMER eine Kopie des ganzen Dokuments in den Speicher. Die Element-Variablen enthalten auch immer Referenzen auf ihre über- und untergeordneten Elemente. D.h. ein einzelnes Element könntest du nur außerhalb des Dokuments speichern, wenn du es per detach() aus dem DOM-Baum herauslöst.
Jede Änderung die du an einem Element vornimmst, wird also im DOM-Baum im Speicher verändert (aber nicht in der Datei, was du ja vermutlich schon weißt).

Und zum Topic:
Es ist offensichlich nicht so leicht, die Anzahl der Kind-Elemente auszulesen... Als ich dir gestern die erste Antwort geschrieben habe, habe ich kurz in einem meiner XML/JDOM-Projekte rumprobiert. Die einzige Methode, die dabei in Frage käme, wäre Element#getContentSize() und die gab mir nicht nachvollziehbare Zahlen zurück. Da mir die Zeit momentan fehlt, mich damit intensiv auseinandersetzen zu können, empfehle ich dir diese Methode zum Ausprobieren.

Viel Erfolg + Gruß
miffi
 
Okay, bin jetzt am Ausprobieren.

Mein Problem ist jetzt nur, dass ich zwar per XPath nun auf das gewünschte Element im Dokiument zugreifen kann, aber dann hab ich ja das Element in einer NodeList. Wie kann man denn von da ausgehend das Element bearbeiten und das Attribut hinzufügen? Oder ist das nicht möglich?

Hier mal ein Auszug, wie ich auf den Knoten zugreife:

Code:
SAXBuilder builder = new SAXBuilder(); 
String testdata = "exc_ruleset_np.xml";					
		
Document doc = builder.build(testdata);
	    	        
XPathFactory factoryX = XPathFactory.newInstance();
XPath xpath = factoryX.newXPath();	
	
XPathExpression expr_count = xpath.compile("//word[last()]");
Object result_count = expr_count.evaluate(doc, XPathConstants.NODESET);
NodeList nodes_count = (NodeList) result_count;
 
Hmm... Ich bin eigentlich davon ausgegangen, dass JDOM ebenfalls eine XPath-Unterstützung hat. Du benutzt jetzt die Klassen aus dem javax.xml.xpath Paket?
Das könnte natürlich schwierig werden, die Knoten mit denen von JDOM zu verheiraten. Da muss ich dir gleich sagen, dass ich mich in dieser Richtung nicht auskenne.

Es wäre jetzt zwar möglich, über die Klassen und Methoden des java.xml-Packages Attribute hinzuzufügen (Stichworte Node und NamedNode), aber das bedeuted auch, dass du zwei verschiedene Technologien für XML verwendest.
Aus diesem Grund habe ich solche Experimente meistens vermieden und mir selbst Methoden geschrieben, wie z.B. über die bereits erwähnte Rekursion.

Es interessiert mich aber auf jeden Fall, wie du das löst.
Auch falls dir hier niemand helfen kann, wärs klasse, wenn du deine Lösung hier beschreiben könntest.
Was natürlich nicht heißt, dass ich es nicht weiter versuchen werde ;)

Gruß
miffi
 
Zurück