# XML - schreiben und einlesen (Schema)



## jaja (29. Sep 2007)

Servus Leute!

zum Ersten hätte ich eine Frage bezüglich des Schreibens einer XML Datei:

Vorgegeben ist mir folgendes Schema:

```
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
```

als XML-Beispiel sieht der Header dann so aus:

```
<markierungen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="markierung.xsd">
```

Meine Frage ist nun, wie ich diese "Parameter" in den Header einer XML Datei setzen kann ???

zum Zweiten folgendes:

Gegeben ist mir ein Schema, dass wie folgt eingelesen wurde:


```
SchemaFactory sfactory = SchemaFactory
    .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
StringReader reader = new StringReader("<xs:schema xmlns:xs=\""
    + "http://www.w3.org/2001/XMLSchema\" elementFormDefault=\""
    + "qualified\">"
    + " <xs:element name=\"markierungen\">"
    + "  <xs:complexType>"
    + "   <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">"
    + "    <xs:element name=\"markierung\" >"
    + "     <xs:complexType>"
    + "      <xs:sequence>"
    + "       <xs:element name=\"id\" type=\"xs:integer\"/>"
    + "       <xs:element name=\"text\" type=\"xs:string\"/>"
    + "       <xs:element name=\"farbe\" type=\"xs:string\"/>"
    + "       <xs:element name=\"position\" type=\"xs:integer\"/>"
    + "       <xs:element name=\"laenge\" type=\"xs:integer\"/>"
    + "       <xs:element name=\"datum\" type=\"xs:string\"/>"
    + "       <xs:element name=\"kommentar\" type=\"xs:string\"/>"
    + "      </xs:sequence>"
    + "     </xs:complexType>"
    + "    </xs:element>"
    + "   </xs:sequence>"
    + "  </xs:complexType>"
    + " </xs:element>"
    + "</xs:schema>");
StreamSource source = new StreamSource(reader);
Schema schema = sfactory.newSchema(source);
```

Wie und mit welcher Java-Bibliothek kann ich entsprechend dieses Schemas andere XML Files auslesen? Ich wäre über ein kleines Codebeispiel oder einen Link in die Richtung sehr dankbar, da ich mich mit XML nicht so wirklich gut auskenne.
*Wichtig* ist hierbei auch noch, dass uns keine fremden Bibliotheken hierzu erlaubt sind!

Vielen Dank !!!


----------



## Wildcard (29. Sep 2007)

Normalerweise lässt man sich aus einem XML Schema Java Klassen erzeugen. Dafür wird ein XML Binding Framework wie JaxB oder EMF verwendet. Wenn das bei dir nicht möglich ist, bleibt dir wohl nur SAX.


----------



## jaja (29. Sep 2007)

mmh, der Aufgabetellung zu folge müssen wir XML-Files auslesen und haben dafür dieses Schema gegeben.

Habe irgendwo gelesen, dass dies mit JSax gehen solle... Ich habe aber leider keine Ahnugn wie und aus google werde ich leider auch nicht schlau.

Kann mir da einer bisschen mehr zu sagen, bzw. mal n kleine sBsp machen :/

Das wäöre echt super..


Ausserdem hab ich auch meine erste Frage leider nicht beantworten können...

Danke für Eure Hilfe!


----------



## Wildcard (29. Sep 2007)

Deine erste Frage ist abhängig von der verwendeten Technik um die XML zu schreiben.


> Habe irgendwo gelesen, dass dies mit JSax gehen solle


Schreibst du nicht selbst, keine Libs verwenden zu dürfen?

Erstmal Grundlagen:
http://www.galileocomputing.de/open...13_003.htm#mj41d15f8dbcc7af6095d9eb5c52ddf163


----------



## jaja (29. Sep 2007)

Hallo!

*zu 1)*
Also, schreiben tue ich wie folgt:


```
XMLOutputFactory factory = XMLOutputFactory.newInstance(); 
         
            XMLStreamWriter writer = factory.createXMLStreamWriter(out);
            
            writer.writeStartDocument();
            writer.writeStartElement("markierung");
..........
```


*zu 2)*
Zu den Libs:

Ich darf keine fremden Libs verwenden, sprich alle regulären Libs aus der Java API sind erlaubt...

Und gegeben ist ein Schema und ich muss mit diesen "Standart-Libs" XML Files entsprechend dem Schema auslesen.


Danke für den Link, in der Insel hatte ich das Zeug schon gelesen. Komme aber leider trotzdem nicht mit oben genannten Problem weiter.. 

thx !


----------



## Wildcard (29. Sep 2007)

Stax ist ebenfalls kein Teil der Standar*d* Java Bibliothek  :roll:


----------



## Guest (29. Sep 2007)

mmmh. und welche möglichkeiten gibt es mit standard-libs diese Aufgabenstellung zu lösen ??? :?


----------



## Wildcard (29. Sep 2007)

Was stört dich an dem Beispiel in der Javainsel?
	
	
	
	





```
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder builder = factory.newDocumentBuilder(); 
    Document document = builder.parse( new File("party.xml") ); 
    System.out.println( document.getFirstChild().getTextContent() );
```


----------



## Guest (29. Sep 2007)

mh, weil da das Schema nicht berücksichtigt wird?!?

oder in wie fern muss das beim auslesen eingfebaut werden ?!?


Ich poste nochmal n kleines Stück aus meiner Aufgabenstellung, vielleich thilft dir das:



> Wichtiger Hinweis: Bitte verwenden Sie zur Lösung dieser Aufgabe ausschließlich die von Java bereitgestellten Klassen. Verwenden Sie keine fremden Bibliotheken!
> 
> Bitte achten Sie darauf, dass Ihr Programm das Schema markierung.xsd nicht über Dateioperationen einliest. Verwenden Sie z.B. folgenden Code:
> 
> ...


----------



## Wildcard (29. Sep 2007)

Du meinst sowas?

```
public class SchemaDemo {
	public static void main(String[] args) throws Exception{
		
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setSchema(createSchema());
		Document doc = factory.newDocumentBuilder().parse(new File("your.xml"));  
	}

	private static Schema createSchema() {
		SchemaFactory sfactory = SchemaFactory
	    .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
	StringReader reader = new StringReader("<xs:schema xmlns:xs=\""
	    + "http://www.w3.org/2001/XMLSchema\" elementFormDefault=\""
	    + "qualified\">"
	    + " <xs:element name=\"markierungen\">"
	    + "  <xs:complexType>"
	    + "   <xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">"
	    + "    <xs:element name=\"markierung\" >"
	    + "     <xs:complexType>"
	    + "      <xs:sequence>"
	    + "       <xs:element name=\"id\" type=\"xs:integer\"/>"
	    + "       <xs:element name=\"text\" type=\"xs:string\"/>"
	    + "       <xs:element name=\"farbe\" type=\"xs:string\"/>"
	    + "       <xs:element name=\"position\" type=\"xs:integer\"/>"
	    + "       <xs:element name=\"laenge\" type=\"xs:integer\"/>"
	    + "       <xs:element name=\"datum\" type=\"xs:string\"/>"
	    + "       <xs:element name=\"kommentar\" type=\"xs:string\"/>"
	    + "      </xs:sequence>"
	    + "     </xs:complexType>"
	    + "    </xs:element>"
	    + "   </xs:sequence>"
	    + "  </xs:complexType>"
	    + " </xs:element>"
	    + "</xs:schema>");
	StreamSource source = new StreamSource(reader);
	Schema schema;
	try {
		schema = sfactory.newSchema(source);
		return schema;
	} catch (SAXException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return null;
	}
}
```


----------



## Guest (29. Sep 2007)

hey, super..! genau sowas habe ich gesucht! 

vielen dank!

jetzt bleibt mir nur noch eine Frage:

ich habe dieses Document als org.w3c.dom.Document importiert. Hoffe das ist das richtge, gehe aber mal von aus!

Wie kann ich jetzt die einzulesene XML datei über eine schöne for-schleife beispielsweise die einzelnen TextContents abfragen ?

Ich konnte nur doc.getFirstChild() beispielsweise finde. Eine Methode getNextChild() oder sowas würde das ganze ja schon einfacher machen. Auch vermisse ich eine Methode, die beispielsweise alle Kinder ausspuckt à la doc.getChildreen() oder sowas?!?

Ich denke, Du weißt was ich meine... So iterator mäßig.

Denn versuche ich doc.getFirstChild().getTextContent() beispielsweise kriege ich nur einen großen Strign ausgespuckt und mit regex zB will ich da nicht dran, da es mit Sicherheit eleganter geht.

Vielen Dank für Deine hilfe!!


----------



## Wildcard (29. Sep 2007)

```
doc.getChildNodes()
```


----------



## Guest (30. Sep 2007)

okay, super!

vielen dank nochmal für deine Hilfe!


----------



## Gast (30. Sep 2007)

Mmmh, ich habe leider immer noch eine Fehlermeldung, die allerdings nur machmal kommt, komischweise:



> com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 1 of 1-byte UTF-8 sequence.
> at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.invalidByte(Unknown Source)
> at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.read(Unknown Source)
> at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(Unknown Source)
> ...



Die jeweilige XML datei spuckt dann folgendes aus:



> Die XML-Seite kann nicht angezeigt werden
> Die XML-Eingabe kann nicht angezeigt werden, wenn Stylesheet XSL verwendet wird. Beheben Sie den Fehler und klicken Sie dann auf Aktualisieren, oder wiederholen Sie den Vorgang später.
> 
> 
> ...




Zeile 310 von NotizSpeicher sieht so aus (da wirft er die Ecxeption):


```
doc = factory.newDocumentBuilder().parse(in);
```

Hat da jemand ne Ahnung?!

Habe schon versucht dem Fehler auf den Grund zu gehen. Habe IE7, aber der Fehler sit immer noch da.

Schreibe ich vielleicht falsch die XML Files ??? Manchmal gehn sie aber, manchmal nicht. Irgendwie ziemlich komisch.

Meine Methode zum Schreiben:


```
public void schreibe(OutputStream out) throws IOException {

        // Initialisiert die entsprechenen Objekte um in die XML-Datei
        // mit Hilfe des FileOutputStreams zu schreiben. Der Name der Datei
        // wurde schon in der Ausgabe.java dem OutputStream uebergeben
        XMLOutputFactory factory = XMLOutputFactory.newInstance();

        try {
            XMLStreamWriter writer = factory.createXMLStreamWriter(out);

            writer.writeStartDocument();
            writer.writeStartElement("markierungen");

            Markierung mark;
            for (int i = 0; i < this.getDats().size(); i++) {

                writer.writeStartElement("markierung");

                mark = this.getDats().get(i);

                writer.writeStartElement("id");
                writer.writeCharacters(this.ids.get(i).toString());
                writer.writeEndElement();

                writer.writeStartElement("text");
                writer.writeCharacters(mark.getText());
                writer.writeEndElement();

                writer.writeStartElement("farbe");
                writer.writeCharacters(mark.getFarbe());
                writer.writeEndElement();

                writer.writeStartElement("position");
                writer.writeCharacters(Integer.toString(mark.getPosition()));
                writer.writeEndElement();

                writer.writeStartElement("laenge");
                writer.writeCharacters(Integer.toString(mark.getLaenge()));
                writer.writeEndElement();

                writer.writeStartElement("datum");
                writer.writeCharacters(mark.getDatum());
                writer.writeEndElement();

                writer.writeStartElement("kommentar");
                writer.writeCharacters(mark.getKommentar());
                writer.writeEndElement();

                writer.writeEndElement();
            }

            writer.writeEndElement();
            writer.writeEndDocument();
            writer.close();
        } catch (XMLStreamException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
```

und die Methode zum Lesen (die inZeile 310 - siehe oben den Fehler wirft):


```
public void lese(InputStream in) throws IOException, SAXException {
        
        this.ids = new ArrayList();
        this.id = 0;
        this.dats = new Vector<Markierung>();        

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setSchema(createSchema());
        Document doc;
        
        try {
            doc = factory.newDocumentBuilder().parse(in);

            // "markierungen"
            NodeList markierungen = doc.getChildNodes();

            // "markierung"
            NodeList markierung = markierungen.item(0).getChildNodes();

            for (int i = 0; i < markierung.getLength(); i++) {

                NodeList inhalt = markierung.item(i).getChildNodes();

                Markierung neu = new Markierung();

                for (int x = 0; x < inhalt.getLength(); x++) {

                    // x == 0 ist die id, die muss allerdings nicht gesetzt
                    // werden sondern wird ueber markierungEinfuegen automatisch
                    // gesetzt

                    switch (x) {
                        case 1:
                            neu.setText(inhalt.item(x).getTextContent());
                            break;
                        case 2:
                            neu.setFarbe(inhalt.item(x).getTextContent());
                            break;
                        case 3:
                            neu.setPosition(Integer.parseInt(inhalt.item(x).getTextContent()));
                            break;
                        case 4:
                            neu.setLaenge(Integer.parseInt(inhalt.item(x).getTextContent()));
                            break;
                        case 5:
                            neu.setDatum(inhalt.item(x).getTextContent());
                            break;
                        case 6:
                            neu.setKommentar(inhalt.item(x).getTextContent());
                            break;
                    }
                }
                
                this.markierungEinfuegen(neu);
            }
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
```


Danke für Eure Hilfe !


----------



## Guest (30. Sep 2007)

-------------------------------------------------------------------------------
hat ich erledigt


----------

