Home
Über mich
Blog
Veröffentlichungen
IT-Trainings
Impressum


XSLT -> JAXB

Um mittels JAXB ein Objekt der Klasse "Person" generieren zu können, wird die folgende XML-Struktur benötigt:

<Person>
    <a>33</a>
    <age>33</age>
    <firstname>Wolkenlos</firstname>
    <lastname>Wilma</lastname>
    <NN>Wilma</NN>
    <VN>Wolkenlos</VN>
</Person>

Ein XSL-Stylesheet, das das vorher dargestellte XML-Dokument (ns3:MENSCH xmlns:ns3="wilfried-grupe.de/jaxb" ...) in die Zielstruktur "<Person>" konvertieren kann, sehen wir hier:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:ns2="wilfried-grupe.de/jaxb/demo"
  xmlns:ns3="wilfried-grupe.de/jaxb">
  <xsl:output method="xml" indent="yes" />
  <xsl:template match="/">
    <xsl:for-each select="ns3:MENSCH">
      <Person>
        <a><xsl:value-of select="@ns2:ALTER1"/></a>
        <age><xsl:value-of select="@ns2:ALTER2"/></age>
        <firstname><xsl:value-of select="vorname"/></firstname>
        <lastname><xsl:value-of select="nachname"/></lastname>
        <NN><xsl:value-of select="NN"/></NN>
        <VN><xsl:value-of select="VN"/></VN>
      </Person>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Mit der folgenden Java-Logik wird eine XSL-Transformation gestartet; das Ergebnis der Transformation wird umgehend mit JAXB in ein Objekt der Klasse Person übernommen. Dabei war es notwendig, das Ergebnis der Transformation in ein ByteArrayOutputStream zu leiten, um den Output-Stream der XSL-Transformation in einen Input-Stream für JAXB umzuwandeln.

  try {
    TransformerFactory tfactory;
    Transformer transformer;
    InputStream is;
    JAXBContext context;
    tfactory = TransformerFactory.newInstance();
    transformer = tfactory.newTransformer(
      new StreamSource(
        new File("Mensch2Person.xsl")));
    Source s = new StreamSource(
      new File("C:/wg/jaxb_demo.xml"));
    ByteArrayOutputStream outputStream;
    outputStream = new ByteArrayOutputStream();
    Result r = new StreamResult(outputStream);      
    transformer.transform(s, r);
    System.out.println("XSL-Transformation OK");
    is = new ByteArrayInputStream(
      outputStream.toByteArray());
    context = JAXBContext.newInstance(Person.class);
    Unmarshaller um = context.createUnmarshaller();
    Person m = (Person) um.unmarshal(is);
    System.out.println("Instanz von Person erstellt");
    System.out.println(m.getVN());
    System.out.println(m.getNN());
    System.out.println(m.getA());
  } catch (TransformerConfigurationException e) {
  } catch (TransformerFactoryConfigurationError e) {
  } catch (TransformerException e) {
  } catch (JAXBException e) {
  }

Ein Vorteil für den XSLT-Ansatz liegt darin, daß sich die fachlichen Anforderungen der Konvertierungen häufig ändern können. Jede Änderung der Klassen "Mensch" (Daten-Lieferant) oder "Person" (Daten-Konsument) kann eine Strukturänderung der gesendeten oder der für JAXB erforderlichen XML-Dokumente nach sich ziehen. Diese Konvertierung kann sehr einfach durch XSLT abgebildet werden.

In diesem Zusammenhang ist vorteilhaft, daß wir in XSLT mehrere Transformationslogiken einbauen können, die verschiedene XML Input-Strukturen in ein einheitliches Zielformat konvertieren, das dann via JAXB in Objekte überführt wird. Damit ist der Daten-Consumer auch in der Lage, mehrere Datenlieferanten unterschiedlichen Typs (.NET, PHP, ...) anzusprechen.

Ebenso leichter lösbar ist damit das häufige Problem, daß der Datenlieferant seine XML-Struktur teilweise (minor change) oder grundlegend (major change) ändert und die Data-Consumer einen zeitlich punktgenauen Switch der Konvertierungslogik vornehmen müssen.

Ein weiterer Vorteil ist, daß der ursprüngliche Inputstream (also der Output der "Mensch"-Klasse) keineswegs in XML vorliegen muß, sondern ein anderes Format haben kann, meinetwegen CSV. Es ist in XSLT 2.0 durchaus möglich, auch Nicht-XML-Formate einzulesen ("unparsed text") und in XML zu konvertieren.

pic/JAXB_XSLT.jpg

Die JAXB vorgeschaltete XSLT-Konvertierung bringt erhebliche Vorteile für die Flexibilität des Datenaustausches. Ohne die verarbeitenden Klassen selbst ändern zu müssen (Neukompilierung nicht erforderlich), kann die komplette XML-XSL-XML-Konvertierung in einer Vorstufe erfolgen.

Sehr sinnvoll ist, das zu transformierende XML Dokument "jaxb_demo.xml" vor der XSL-Transformation gegen ein XML Schema zu validieren. Auf diese Weise sollte sichergestellt werden, daß sich die Struktur des XML Dokuments nicht grundlegend geändert hat, mit der möglichen Folge eines gravierenden Informationsverlustes.

qrpic/Datenaustausch6.jpg

wg / 14. Oktober 2017




Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf (info10@wilfried-grupe.de).



Vielen Dank für Ihr Interesse an meiner Arbeit.


V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

Mobil: 0151. 750 360 61 * eMail: info10@wilfried-grupe.de