Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

xml, jdom and following-sibling

Status
Not open for further replies.

bateman23

Programmer
Mar 2, 2001
145
DE
Hello,

short version: Is there a possibility using jdom to get the "following-sibling" of an element.

long version: Assume i've got the following xml file:

<party datum="31.12.01">
<gast>
<person>
<name>Albert Angsthase</name>
</person>
<getraenk>Wein</getraenk>
</gast>
<gast>
<person>
<name>Martina Mutig</name>
</person>
<getraenk>Apfelsaft</getraenk>
</gast>
<gast>
<person>
<name>Zacharias Zottelig</name>
</person>
</gast>
</party>

Now i want a list of all names of the guests.
At the moment i' using jdom in the follow java-class:

listChildren(myfile.doc.getRootElement());
calls this function:

public static void listChildren(org.jdom.Element current) {

//Array
String laenderarray[] = new String[10];
int anzahl = 0;

System.out.println(current.getName());
java.util.List children = current.getChildren();
java.util.Iterator iterator = children.iterator();
while (iterator.hasNext()) {
org.jdom.Element child = (org.jdom.Element) iterator.next();
System.out.println(child);
String temp = child.getName();
System.out.println("Name: " + temp);
if(temp == "name") {
System.out.println("Name ist: " + child.getText());
laenderarray[anzahl] = child.getText();
anzahl++;

// here's the problem. I don't want to search the next children, but
// get the "following sibling"
// that gets me to the actual <guest>
//child = child.getParent().getParent();
// but how do i get to the next one ??
}
// go on
listChildren(child);
}
}

I haven't found any way to do this in jdom... Isn't there any ?
If i have to use jaxen and xpath (i don't hope so), how do i have to do this - i have absolutly no idea.
Thanx in advance for any response,

daniel

---------------------------------------
Visit me @:
 
I may be misunderstanding ( I do not speak german so your XML entities do not make sense to me ) but it -sounds- like you are assuming that the in the XML you will be getting an ordered response back. ie:

Code:
    <person>
        <name>Albert Angsthase</name>
    </person>
        <getraenk>Wein</getraenk>

That the 'getraenk' element following the 'person' element will always relate to the person. Unfortunately XML does not promise proper element ordering. If getraenk is an attribute of person it should live inside person to build the relationship.

I sorry if I misunderstood your question.
 
Hi,
ups, sorry - haven't thought about that. but no, that's not what i want to do. I'll give the english version of the xml file (with comments), perhaps it's getting a bit clearer what i want...

Code:
<party date="31.12.01">
    <guest>
	<person>
		<name>Albert Angsthase</name>
		<!-- i want to get that name-->
	</person>
	<!-- see comment 1- here comes a lot of tags -->
        <drink>wine</drink>
        <drink>beer</drink>
     </gust>
    <!-- that's where i want to jump, getting the name "Martina Mutig" -->
    <guest>
 	<person>
		<name>Martina Mutig</name>
	</person>
        <drink>Apfelsaft</drink>
     </guest>
    <guest>
	<person>
		<name>Zacharias Zottelig</name>
	</person>
    </gast>
</party>

comment 1:
here comes a lot of other tags.. about 1000 lines...
so i don't want the program to run through all this tags, where it definitly doesn't find any other <guest><person><name> things.
Instead it should go 2 steps up (back to guest) and get the following-sibling - in this case the next guest. There it should run as normal, which means find the name inside the perosn tag... and so on...

---------------------------------------
Visit me @:
 
Then you should not be using listChildren, its a recursive routine that lists the entire datastructure.

What I would do is :

1) get the root element
2) Get the guest elements into a list
3) for each guest element in the list do your magic with the person thing
4) Back to 3 until the list is exhausted.

That seems to make more sense. You do not need the recursive routine for this, you just need to access the guest elements as a list and iterate through them using a list iterator.

 
Yes, but exactly "2) Get the guest elements into a list" is my problem:
the jdom-method getchildren() lists ONLY the child-elements (in my case the <guest>tags. What i need is the content behind <guest> (the names !!). My idea was using getContent() instead of getchildren(). This should list all children of each element. And that's the other extreme: It lists everything. Even the children of the children of the children....

I need something in between:
I want to go through the tree with getContent, but if jdom has found the persons name, it should get back to <guest> and find the following sibling.
Aren't there any technics built into jdom to achieve this?

Actualy i'm working on a solution based on jaxen and xpath. But anyway i still wonder if there's any possibility to do this in "pure" jdom..

---------------------------------------
Visit me @:
 
Use

getChildren(java.lang.String name)
and
getChild(java.lang.String name)

So you can say

List elementList = rootElemenet.getChildren("guest") ;


Now you have a list of elements to iterate through that represent each guest

for each of those elements you can now call

personElement = listElement.getChild("person");

Now you can access personElement

 
thanx.
To complete the thread, here's my solution using jaxen and xpath:

Code:
public void getlaender() {

  java.util.List results = xtree.jdomModel.listChildren(myfile.doc);

  laenderarray = new String[results.size()];
  cmblaender.removeAllItems();

  for(int i=0; i<results.size();i++) {
    String temp2 = "" + results.get(i); //""+ wegen cast
    temp2 = temp2.substring(7,temp2.length()-1);
    cmblaender.addItem(temp2);

    int j = i+1;
    laenderarray[i] = "/java/object/void[" + j + "]/object";

  } // end for
}

acalling this function:

Code:
 public static java.util.List listChildren(org.jdom.Document doc) {

   java.util.List results = null;

  try {

    //Jaxen XPath Konstruktor
    XPath xpath = new org.jaxen.jdom.JDOMXPath("/java/object/void/string/text()");

    //Evaluate the results
    results = (java.util.List) xpath.evaluate(doc);

  }
  catch (JaxenException e) {
    e.printStackTrace();
  }

  return results;
 }

---------------------------------------
Visit me @:
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top