XML Attribute auslesen

Häcki.

Mitglied
Hallo Leute,

ich habe folgende XML-Struktur: http://www.openthesaurus.de/synonyme/search?q=Synonym&format=text/xml

Nun möchte ich in Java beispielsweise aus dem ersten Synset-Element alle Kindelemente, die "term" heißen - und von denen benötige ich jeweils das Attribut "term", speziell: dessen Wert.

Im Beispiel wäre das also folgendes, was ich gern (am liebsten) in einem Array hätte:
andere Bezeichnung, anderes Wort für, bedeutungsgleiches Wort, Ersatzwort, Synonym

Der aktuelle Ansatz (Auszug davon - das sollte ja das sein, was wichtig ist) dafür ist folgender:
Java:
	private static void DisplayResults(Document doc) throws XPathExpressionException 
	{
		String searchTerms = "Synonym"
		NodeList results = (NodeList)xpath.evaluate("//matches/synset/term/@term", doc, XPathConstants.NODESET); 

		// Display the results header.
		System.out.println("Web results for " + searchTerms);
		System.out.println();

		// Display the Web results.
		StringBuilder builder = new StringBuilder();
		
		for(int i = 0 ; i < results.getLength(); i++)
		{
			NodeList childNodes = results.item(i).getChildNodes();

			for (int j = 0; j < childNodes.getLength(); j++) 
			{
				if(!childNodes.item(j).getLocalName().equalsIgnoreCase("DisplayUrl"))
				{
					String fieldName = childNodes.item(j).getLocalName();

                                        System.out.println(childNodes.item(j).getTextContent());
					rueckgabe[i][j] = fieldName + ":" + childNodes.item(j).getTextContent();
					builder.append(fieldName + ":" + childNodes.item(j).getTextContent());
					builder.append("\n");
				}
			}

			builder.append("\n");
		}

		System.out.println(builder.toString());
	}

Gibt mir bisher natürlich nur folgende Ausgabe:
Web results for Synonym
Tipps & Tricks?
 
Zuletzt bearbeitet:
sowas?

Java:
package org.sourceprojects.lycia.incubator.test;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
import org.sourceprojects.lycia.XmlParser;
import org.sourceprojects.lycia.XmlParserBuilder.GenerationStrategy;
import org.sourceprojects.lycia.fluent.FluentBuilder;
import org.sourceprojects.lycia.incubator.annotations.Attribute;
import org.sourceprojects.lycia.incubator.annotations.ContextObject;
import org.sourceprojects.lycia.incubator.internal.generator.AnnotatedParameterReflectiveGenerator;

import static org.junit.Assert.*;
import static org.sourceprojects.lycia.fluent.FluentBuilder.*;

public class TermParserTestCase {
	private static final String XML_DATA = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<matches><synset><term term=\"foo\" /><term term=\"bar\" /><term /></synset></matches>";

	@Test
	@SuppressWarnings("unchecked")
	public void testXmlPathConfigure() throws Exception {
		Method method = getClass().getMethod("parseData", List.class,
				String.class);

		FluentBuilder<List<String>> builder = prepare();
		builder.configure(validateSchema(false));
		builder.configure(generationStrategy(GenerationStrategy.Customized,
				AnnotatedParameterReflectiveGenerator.class));
		builder.parser(xpath("//matches/synset/term[@term]", method(method,
				this)));

		XmlParser<List<String>> xmlParser = builder.build();

		xmlParser.getParserContext().setContextObject(new ArrayList<String>());

		xmlParser.parse(XML_DATA);
		List<String> values = xmlParser.getParserContext().getContextObject();

		assertEquals(2, values.size());
		assertEquals("foo", values.get(0));
		assertEquals("bar", values.get(1));
	}

	public void parseData(@ContextObject List<String> values,
			@Attribute("term") String value) {

		values.add(value);
	}

}
 
Zuletzt bearbeitet:
Was machst du denn an folgender Stelle?

[JAVA=41] assertEquals(2, values.size());
assertEquals("foo", values.get(0));
assertEquals("bar", values.get(1));
[/code]
 
Ich benutze hier Lycia. Ich habe das einfach nur fix als Unittest implementiert und mit den 3 Zeilen prüfe ich, ob die aus dem Parser kommenden Werte das sind war ich vermute 🙂
 
Ah, nun gut okay - ich glaub den Lycia lasse ich erstmal weg. Wobei der recht interessant aussieht. Aber ehe ich mir da jetzt zig Packages wieder installieren muss (hat jemand von euch schonmal mit JADE gearbeitet? Ich hasse solche Agentensysteme ...), bleibe ich erstmal beim SAXParser. In einer freien Minute schau ich mir den Lycia mal genauer an. Danke für den Tipp!

Neue Version des Codes, der sogar mittlerweile ein wenig funktioniert:
Java:
import org.w3c.dom.Document;
import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException; 

public class Syn2
{
    public static void main(String argv [])
    {
	    try 
	    {
	    	DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
	        DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
	        Document doc = docBuilder.parse("http://www.openthesaurus.de/synonyme/search?format=text/xml&q=Synonym");
	
	        // normalize text representation
	        doc.getDocumentElement().normalize();
	        System.out.println ("Root element of the doc is " + doc.getDocumentElement().getNodeName());
	
	        NodeList listOfSyn = doc.getElementsByTagName("synset");
	        int totalSyns = listOfSyn.getLength();
	        System.out.println("Total no of synsets: " + totalSyns);
	
	        for(int s=0; s < listOfSyn.getLength(); s++)
	        {
	            Node synsetNode = listOfSyn.item(s);
	            if(synsetNode.getNodeType() == Node.ELEMENT_NODE)
	            {
	                Element termMainElement = (Element)synsetNode;
	                NodeList termList = termMainElement.getElementsByTagName("term");
	                Element termElement = (Element)termList.item(0);
	                System.out.println(termElement.getAttribute("term"));
	            }
	        }
	    }
	    catch(SAXParseException err)
	    {
	        System.out.println ("** Parsing error" + ", line " + err.getLineNumber () + ", uri " + err.getSystemId ());
	        System.out.println(" " + err.getMessage ());
	    }
	    catch(SAXException e)
	    {
	        Exception x = e.getException();
	        ((x == null) ? e : x).printStackTrace ();
	    }
		catch(Throwable t)
		{
		    t.printStackTrace ();
		}
	    //System.exit (0);
    }
}

Gibt mir allerdings nur das jeweils erste Ergebnis eines jeden Synsets aus - soweit ich das nachvollziehen kann ist das wohl auch logisch (zumindest irgendwie ...).

Der "Fehler" liegt vermutlich hier:
[JAVA=26] for(int s=0; s < listOfSyn.getLength(); s++)
{
Node synsetNode = listOfSyn.item(s);
if(synsetNode.getNodeType() == Node.ELEMENT_NODE)
{
Element termMainElement = (Element)synsetNode;
NodeList termList = termMainElement.getElementsByTagName("term");
Element termElement = (Element)termList.item(0);
System.out.println(termElement.getAttribute("term"));
}
}[/code]

Speziell der Teil in der IF-Bedingung.
Kann mir jemand sagen, wie ich nun noch noch ALLE Terms innerhalb des jeweiligen Synset ausgegeben bekomme?
Ich muss wohl irgendwie hieran arbeiten:
Element termElement = (Element)termList.item(0);

Wie bekomme ich denn die Anzahl der TERM-Elemente ermittelt? Wenn ich das hätte, wäre es kein Problem das in einer FOR-Schleife z.B. auszugeben.
Tipps/Tricks?

Edit:
So schwer war es dann doch nicht:
[JAVA=33] int number = termList.getLength();
for(int i = 0; i < number; i++)
{
Element termElement = (Element)termList.item(i);
System.out.println(termElement.getAttribute("term"));
}[/code]
 
Zuletzt bearbeitet:

Zurück
Oben