XML aus einem normalen String parsen

socke999

Erfahrenes Mitglied
Hallo,
kennt jemand eine Möglichkeit einen Simplen String der xml enthält zu parsen?

Es geht um folgendes:
Ich habe in meinen Java-Programm einen simplen String der xml enthält.
z.B. So was:

Code:
String s = "<myatribute name=\"Mein Name\" > Beispiel Text   </myatribute>";

Nun, soweit ich gesehen habe, gibt es 2 möglichkeiten ein XML File in JAVA zu parsen.
JDom und Sax.

jedoch parsen beide immer nur ein xml File, ich möchte aber nur einen einfachen XML-String parsen.

und am besten so wie JDOM die einzelnen Elemente und Attribute abfragen können wäre super.

Kennt jemand so etwas? Oder kann jemand da weiter helfen?
 
Zuletzt bearbeitet:
Tjo Java ist da ein bisschen schwach auf der Brust:
http://stackoverflow.com/questions/247161/how-do-i-turn-a-string-into-a-stream-in-java
C++ kennt stringstreams, in .Net gibts ... OOPS auch nix, siehe hier.
Ganz schönes Trauerspiel...

Java:
public class Main {
	
	public static void main(String[] args) throws Exception {

		String xml = "<hi><ho>data</ho></hi>";
		ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes(Charset.defaultCharset()));
		SAXParserFactory factory = SAXParserFactory.newInstance();
		SAXParser p = factory.newSAXParser();
		p.parse(bais, new DefaultHandler() {
			@Override
			public void startElement(String uri, String localName,
					String qName, Attributes attributes) throws SAXException {
				System.out.println(qName);
			}
		});
	}
	
}
 
Zuletzt bearbeitet von einem Moderator:
In Java kann man den StringReader nutzen. Der funktioniert genau wie der InputStreamReader. Ist auch logisch, da er das gleiche Interface implementiert . ;-)

Java:
import java.io.StringReader;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class StringXMLExample {

	public static void main(String[] args) throws Exception {
		String xml = "<hi><ho>data</ho></hi>";
		StringReader reader = new StringReader(xml);
		SAXParserFactory factory = SAXParserFactory.newInstance();
		SAXParser p = factory.newSAXParser();
		p.parse(new InputSource(reader), new DefaultHandler() {

			public void startElement(String uri, String localName,
					String qName, Attributes attributes) throws SAXException {
				System.out.println(qName);
			}
		});
	}

}

Gruß

Sascha
 
In Java kann man den StringReader nutzen. Der funktioniert genau wie der InputStreamReader. Ist auch logisch, da er das gleiche Interface implementiert . ;)
Ja, OK. Aber beide implementieren keinen InputStream. und da liegt der Hund begraben.
Der "Trick" ist die InputSource, die das wegkapselt.
Das heißt, SAX-intern muss irgendwo zwischen Stream und Reader unterschieden werden.

Java:
p.parse(new InputSource(reader), new DefaultHandler() {

Stellt sich noch die rhetorische Frage, warum das SAX wohl so macht :D
 
Zuletzt bearbeitet von einem Moderator:
Das heißt, SAX-intern muss irgendwo zwischen Stream und Reader unterschieden werden.

Naja, groß wird da auch nicht unterschieden. Denn intern wird der Stream auch in eine InputSource gepackt.
Code:
 public void parse(InputStream is, DefaultHandler dh)
        throws SAXException, IOException {
        if (is == null) {
            throw new IllegalArgumentException("InputStream cannot be null");
        }

        InputSource input = new InputSource(is);
        this.parse(input, dh);
    }

Meiner Meinung nach ist der einzige Grund, warum direkt Methoden mit Streams angeboten werden ist, dass man meistens die XML-Daten aus irgendeinem Input-Stream bekommt.

Gruß

Sascha
 
So habe ich das nicht betrachtet :) Da ist die API schon ein wenig komisch.
Was ich gemeint habe ist dass die Reader und die InputStream nichts miteinander gemein haben, und die InputSource quasi eine Abstraktion über beide darstellen, die intern von der Parser-Infrastruktur genutzt wird.

Ich hab mir gerade die OpenJDK 6 Sourcen gezogen, und wollte mal ein bisschen reinschnuppern.
Sind das die richtigen Sourcen?
 
Tach auch,

Was ich gemeint habe ist dass die Reader und die InputStream nichts miteinander gemein haben,
Naja - haben sie schon - beides sind Streams - die InputStreams sind ByteStreams und die Reader CharacterStreams.

Die InputSource bietet den Parsern die Möglichkeit abzufragen, ob die Daten als ByteStream (InputStream) oder bereits als CharacterStream vorliegen (Reader). Im letzteren Fall spart sich der Parser das Umwandeln, was er ja bei ByteStreams erst mal machen muss.

Gruß
THMD
 
Was meinst du damit? Es sind die Sourcen einer JDK-Implementierung.

Hmm, also beim reindebuggen sah das gerade nicht gut aus. (OK, hätte ich auch selber draufkommen können...)
Ich ziehe gerade noch die jdk6 source direkt von java.sun.com.
Was mich da schon wieder stutzig macht ist dass die Source-Datei "jdk-6u18-..." heißt, es aber nur ein JDK "jdk-6u17..." gibt. Naja, das wird hoffentlich dann passen.

Was mich an der Geschichte gerade noch interessiert ist wer innerhalb der Klassenkonglomerats die Konvertierung InputStream -> Reader (oder andersrum) macht, oder ob das überhaupt gemacht wird. Beim statischen Durchgucken hab ich irgendwann die Übersicht verloren :D Hab nur gesehen dass die InputSource munter durch die Gegend geschoben wird...
Ich hatte erwartet dass die InputSource Klasse die Konvertierung macht, aber die macht ziemlich genau gar nichts.

OK, also intern gibts noch einen XMLInputSource, die wiederum nichts mit InputSource zu tun hat. Der werden einfach alle Daten anvertraut.
Nach einigem Suchen: Das wird im XMLEntityManager gemacht, Methode #setupCurrentEntity(). Puh, da wird einiges mit spezifischen Encodings gemacht.
Der InputStream wird zuerst in einen RewindableInputStream gewrappt, und dann in einen UTF8Reader, ASCIIReader oder BufferedReader.

Was für ein Aufwand ;)
 
Zuletzt bearbeitet von einem Moderator:
Zurück