# Xsd file in Java lesen und als JTree darstellen.



## martinsig (5. September 2007)

Hallo,

ich muss ein xsd file in java einlesen und als ein jTree darstellen.
Achtung. Kein xml file! Es ist ein xsd file.
Mit welchem Parser geht denn das am besten? 
Wie sollte ich am besten vorgehen.

Vielleicht kennt es ja jemand. Es sollte so wie in oXygen aussehen, wenn man sich eine xsd Datei in der logischen Baumdarstellung ansieht. 

Vielen vielen Dank


----------



## zeja (5. September 2007)

Eine XML Schema Definition wird selbst in XML notiert. Ein XML-Parser wird also das tun was du möchtest.


----------



## zerix (5. September 2007)

Hallo,

ein XSD-File ist auch ein XML-File, also müsste es mit einem normalen XML-Parser funktionieren.

http://www.tutorials.de/forum/java/171731-xml-baum-jtree-abbilden.html

Wie der Baum letztendlich aussehen soll, musst du mir einem CellRenderer definieren.

MFG

zEriX


----------



## martinsig (5. September 2007)

Hallo,

danke für die schnellen Antworten. Mein problem liegt darin wie ich den Baum am geschicktesten zusammenbau. Da es sich um eine xsd Datei handelt, ist die Struktur nicht wirklich als eine Baumstruktur erkennbar. 
Ich will mal ein Beispiel geben wie ich einige xsd elemente als Baum darstellen würde.
...
<xs:complexType name="Person">
    <xs:sequence>
       <xs:element name="Vorname" type="String" />
       <xs:element name="Nachname" type="String" />
      </xs:sequence>
  </xs:complexType>
...
<xs:complexType name="Gruppe">
    <xs:sequence>
       <xs:element name="Mitglied" type="Person" />
       <xs:element name="GruppenName" type="xs:String" />
      </xs:sequence>
  </xs:complexType>
<xs:complexType name="Haus">
    <xs:sequence>
       <xs:element name="Bewohner" type="Person" />
       <xs:element name="Hausnummer" type="xs:Integer" />
      </xs:sequence>
  </xs:complexType>

Daraus würde ich gern folgenden baum haben:

```
root + Person 
                 + Vorname
                 + Nachname
        + Gruppe
                  + Person 
                              + Vorname
                              + Nachname
                 + Gruppenname
        + Haus
                 + Person
                              +Vorname
                              +Nachname
                + Hausnummer
```

Vielen Dank.
Schöne Grüße


----------



## zeja (5. September 2007)

Erstmal solltest du dir eine Datenstruktur überlegen in welche du die geparsten Daten ablegen kannst so dass du sie später leicht in einen Baum umwandeln kannst.

Sind die Daten fertig geparst gehst fängst du an den Baum aufzubauen. Dabei schaust du bei jedem Element im Typ nach ob dies ein Standardtyp ist oder ob dieser in deinen geparsten Daten zu finden ist (Name als Key und Objekt als Value in eine HashMap z.B.). Ist dies der Fall nutzt du die Daten des gefundenen Typs im Baum.


----------



## kw4nta (9. Dezember 2011)

martinsig hat gesagt.:


> Hallo,
> 
> ich muss ein xsd file in java einlesen und als ein jTree darstellen.
> Achtung. Kein xml file! Es ist ein xsd file.
> ...




XSD kann man mit Xerxes einlesen (+ zugehöriges XML)


```
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.apache.xerces.xs.ElementPSVI;
import org.apache.xerces.xs.XSAnnotation;
import org.apache.xerces.xs.XSElementDeclaration;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public final class DocumentManager
{
	Document loadDocument(String documentURL) throws Exception
	{
		
		InputStream in = new URL(documentURL).openStream();
		Document doc = builder.parse(in);
		in.close();
		if (!doc.getDocumentElement().isSupported("psvi", "1.0"))
			throw new Exception("apache xerxes psvi not supported");
		return doc;
	}
	
	DocumentBuilderFactory dbf;
	DocumentBuilder builder;
	
	public DocumentManager(String schemaURL) throws Exception
	{
		// Builder parser = new Builder(false);
		// Document doc = parser
		// .build(new File(
		// new URI(
		// "file:///C:/developer/workspace/2011-11-23%20rulesmanager%20prototype/mapping-schema.xsd")));
		// Element root = doc.getRootElement();
		// Load up the document
		dbf = DocumentBuilderFactory.newInstance();
		
		// dbf is JAXP DocumentBuilderFactory
		
		// all of the following features must be set:
		dbf.setNamespaceAware(true);
		dbf.setValidating(true);
		dbf.setAttribute("http://apache.org/xml/features/validation/schema",
				Boolean.TRUE);
		
		// you also must specify Xerces PSVI DOM implementation
		// "org.apache.xerces.dom.PSVIDocumentImpl"
		dbf.setAttribute(
				"http://apache.org/xml/properties/dom/document-class-name",
				"org.apache.xerces.dom.PSVIDocumentImpl");
		
		// Set up an XML Schema validator, using the supplied schema
		;
		InputStream in = new URL(schemaURL).openStream();
		Source schemaSource = new StreamSource(in);
		SchemaFactory schemaFactory = SchemaFactory
				.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
		Schema schema = schemaFactory.newSchema(schemaSource);
		
		// Instead of explicitly validating, assign the Schema to the factory
		dbf.setSchema(schema);
		
		// Parsers from this factory will automatically validate against the
		// associated schema
		builder = dbf.newDocumentBuilder();
		in.close();
	}
	
	Document createDocument() throws Exception
	{
		Document doc = builder.newDocument();
		if (!doc.getDocumentElement().isSupported("psvi", "1.0"))
			throw new Exception("apache xerxes psvi not supported");
		return doc;
	}
}


//use like

		DocumentManager m = new DocumentManager(
				"schema.xsd");
//jetzt entweder passendes XML laden
		Document d = m
				.loadDocument("document.xml");
		String ns = d.getDocumentElement().getNamespaceURI();
		ElementPSVI e = (ElementPSVI) d.getElementsByTagNameNS(ns, "if-rule")
				.item(0);
		XSElementDeclaration decl = e.getElementDeclaration();
//oder Dokument erzeugen

		Document d = m
				.createDocument();

		ElementPSVI e = (ElementPSVI) d.createElementNS("your-namespace", "root-element-tag");

//et voilà: die Deklaration des root Elements.
		XSElementDeclaration  decl = e.getElementDeclaration();
```
Jetzt musst du dich nur noch in die XSAPI von Xerces einarbeiten.

Greetz
Kwanta


----------



## vfl_freak (9. Dezember 2011)

Moin,



kw4nta hat gesagt.:


> XSD kann man mit Xerxes einlesen (+ zugehöriges XML)
> 
> Jetzt musst du dich nur noch in die XSAPI von Xerces einarbeiten.



na, ob er das nach über 4 Jahren  noch möchte ....... ich weiß es nicht ...... 

Gruß
Klaus


----------



## kw4nta (9. Dezember 2011)

Ich habe ewig nach dieser Lösung gesucht, bin unter anderem auch auf diesen Post gestoßen. Deshalb hab ich gedacht, ich poste mal meine Lösung. Hätte vielleicht was zum Datum sagen sollen


----------



## schnuffie (11. Dezember 2011)

Eine XSD mit einem XML-Parser einzulesen und als Baum auszugeben, erfordert viel "Handarbeit". Ich würde aus der XSD mit JAXB-Tool die Klassen generieren lassen: "jaxb\bin\xjc.bat schoko.xsd -d src -p jaxb.schoko.generated", siehe dazu auch http://www.tutorials.de/java/224045-jaxb-und-konkrete-klassen-erstellen.html.

Durch die Beziehungen zwischen den Klassen kannst Du diese optimal für den Aufbau des Baums benutzen.


----------

