Validation im RAM

Hallo,

ich habe viele Objekte im RAM die jeweils zu einer xml-Datei korrespondieren. Weitehin haben alle Objeke eine Methode die mir ein Objekt vom Typ org.jdom.Document liefern.

Ich würde nun gerne Schematas initial in den RAM laden (wohl auch als org.jdom.Document) und zur Laufzeit gegen meine Objekte validieren um andauernden Plattenzugriff zu vermeiden.

Geht das mit JDom oder evtl. über Umwege mit Hilfe von InputStreams? Den String-content der Document-Objekte bekomme ich ja auch. Gibt es Möglichekeiten direkt mit dem Dateiinhalt anstatt der Files zu validieren?

Vielen Dank und Grüße,
Jorsch

Hallo,

Ich würde nun gerne Schematas initial in den RAM laden und zur Laufzeit gegen meine
Objekte validieren um andauernden Plattenzugriff zu vermeiden.

Geht das mit JDom oder evtl. über Umwege mit Hilfe von
InputStreams?

Wenn ich diesen FAQ Eintrag richtig interpretieren funktioniert das mit JDOM direkt wohl nicht: http://www.jdom.org/docs/faq.html#a0370

Es müsste IMHO allerdings auf Umwegen trotzdem funktionieren, wenn du die Schema wie hier initialisierst und in einer globalen Variablen ablegst:

import org.jdom.Document;
import org.jdom.input.SAXBuilder;
import org.jdom.output.DOMOutputter;

import javax.xml.XMLConstants;

import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.xml.sax.SAXException;

// ...

public static void validate() throws Exception
{
 SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C\_XML\_SCHEMA\_NS\_URI);

 Source schemaSource = new StreamSource(new File("example.xsd"));
 Schema sch = factory.newSchema(schemaSource);

 SAXBuilder builder = new SAXBuilder();
 Document doc = builder.build(new java.io.File("example.xml"));
 System.out.println("Document: " + doc);

 DOMOutputter out = new DOMOutputter();
 org.w3c.dom.Document w3cDoc = out.output(doc);

 try
 {
 Validator validator = sch.newValidator();
 validator.validate(new DOMSource(w3cDoc));
 System.out.println(" XML File is valid!");
 }
 catch (SAXException e)
 {
 // File is invalid
 System.out.println();
 System.out.println(" XML File is invalid: ");
 System.out.println(" " + e.getMessage());
 }

}

HTH
Heavy

Hallo Heavy,

das sieht doch sehr gut aus, danke!

Zwei Fragen hätte ich noch:

1.) Mein Schema benutzt Namespaces und xsd:import. Es werden also Elemente aus anderen Dateien via xmlns-Attribut und Schemata via import angefordert.

Funktioniert dies auch oder läd er dann doch nach beim validieren?

2.) Ich werde viele xml Dateien haben, die sehr groß sind (> 60 MB). Komprimiert bekomme ich die Dateien aber locker unter ein MB.

Hier sollte ich doch den gleichen Trick anwenden können, oder? (falls dies auch mit den Komprimierungsbibliotheken funktioniert)

Also z.B.

  • Komprimierte Datei einlesen.
  • XML-Inhalt direkt als String (oder Stream) in den RAM dekomprimieren
  • String im RAM in ein Objekt parsen
  • Mit Objekt arbeiten
  • Objekt im RAM zu XML-String wandeln
  • Im RAM eine Datei mit String als Content komprimieren
  • Komprimierte Datei auf die Platte schreiben

Könnte dieser Ansatz funktionieren oder gibt es da einen Punkt, wo meine Überlegung nicht hin haut?

Gruß,
Jorsch

1.) Mein Schema benutzt Namespaces und xsd:import. Es werden
also Elemente aus anderen Dateien via xmlns-Attribut und
Schemata via import angefordert.

Funktioniert dies auch oder läd er dann doch nach beim
validieren?

Das müsste ich auch ausprobieren, ich vermute aber, nachdem das Schema oder gar Validator Objekt initialisiert ist sind keine Plattenzugriffe mehr notwendig.

2.) Ich werde viele xml Dateien haben, die sehr groß sind (>
60 MB). Komprimiert bekomme ich die Dateien aber locker unter
ein MB.

Also z.B.

  • Komprimierte Datei einlesen.
  • XML-Inhalt direkt als String (oder Stream) in den RAM
    dekomprimieren
  • String im RAM in ein Objekt parsen
  • Mit Objekt arbeiten
  • Objekt im RAM zu XML-String wandeln
  • Im RAM eine Datei mit String als Content komprimieren
  • Komprimierte Datei auf die Platte schreiben

Die SAXBuilder Klasse besitzt eine Methode, die einen InputStream erwartet, das kann auch ein GZIP- oder ZipInputStream sein, wenn die XML Dateien komprimiert sind.

Aber brauchst du immer das komplette XML Dokument, oder enthält das eine immer wiederkehrende Elementstruktur? In letzterem Fall bietet sich evtl. eine Event-basierte Verarbeitung an. Ich weiss allerdings nicht ob JDOM das unterstützt, da ich immer dom4j nutze: http://www.dom4j.org/dom4j-1.6.1/faq.html#large-doc

Gruß
Heavy