Zurück

Akadia Information Technology


René Steiner, Akadia AG, Information Technology, Arvenweg 4, CH-3604 Thun
Phone: +41 33 335 86 22 / Fax: +41 33 335 86 25 / EMail: rene.steiner@akadia.com

Einleitung

XML findet mehr und mehr Verwendung in unterschiedlichsten Applikationen zur standardisierten, dateibasierten Speicherung und Übertragung von Daten. Von dieser plattformübergreifenden Datenbeschreibungssprache wird ein grosser wirtschaftlicher Nutzen in B2B (Business-to-Business) Anwendungen erwartet. Eine grosse Anzahl zusätzlicher API's und Tools stehen von verschiedensten Herstellern zur Verfügung. In diesem Artikel sind grundsätzliche Erklärungen ausgewählter Themen zu finden. Ergänzend zu unserem Artikel existieren viele weitere Möglichkeiten, die in der Literatur und in Handbüchern detailliert erläutert werden.

Inhalt

Unser Artikel behandelt die folgenden Themen:

Einführung in XML

XML steht für eXtensible Markup Language und beschreibt den Inhalt eines Dokumentes. Eine XML Datei besteht im wesentlichen aus einzelnen Datenfeldern, zum Beispiel aus den Feldnamen Strasse und Ort in einer Adresse, dazu den Strassennamen und die Ortschaft selbst als Daten. Im Gegensatz zu XML beschreibt HTML die Darstellung von Daten. In HTML werden beispielsweise Absätze <p>, Fonts <font> und Typen von Überschriften <h2> definiert.

Mit XML wird der Inhalt von der Darstellung getrennt. Ein XML Client kann die Daten darstellen, sofern dies erwünscht ist. Die Möglichkeiten dazu werden später in diesem Artikel aufgezeigt.

XML ist ein plattformunabhängiger Standard des W3C Konsortiums, aktuell ist die XML Version 1.0, zur Zeit auch die einzige, die bisher herausgegeben wurde. XML ist ein Teil der Standard Generalized Markup Language SGML. SGML wurde durch ISO standardisiert und entstand bei IBM zur Formatierung von Dokumenten. SGML ist sehr umfangreich, bei XML, als Subset von SGML, hat man sich auf die wesentlichen Eigenschaften von SGML beschränkt.

Aufbau und die Struktur von XML

Eine Kundenbestellung als Beispiel soll die wesentlichen Teile erläutern, diese könnte von einem externen System transferiert worden sein. Es handelt sich um eine reine Datenbeschreibung, es fehlen jegliche Anweisungen zur Darstellung.

XML Kundenbestellung: Order.xml

<?xml version="1.0" encoding="UTF-8"?>                        (1)
<!DOCTYPE order SYSTEM "Order.dtd" [                          (2)
   <!ENTITY auml "&#228;">
]>
<order>                                                       (5)
   <!-- Auftragsnummer -->
   <id>74836647</id>
   <item>
      <article>324-67511</article>                            (9)
      <name>Geh&auml;use</name>
      <number>20</number>
      <style>
         <color>rot</color>
         <doors>2</doors>
         <connectors>2</connectors>
      </style>
      <manufacturer>Shelves &amp; Cabinets Ltd.</manufacturer>
   </item>
   <item>
      <article>655-01345</article>
      <name>Kabelrolle</name>
      <number>10</number>
      <style>
         <color>grau</color>
         <width>300</width>
      </style>
      <manufacturer>Kabel AG</manufacturer>
   </item>
</order>

Processing Instruction (Zeile 1)

<?xml version="1.0" encoding="UTF-8"?>

Die Bestellung beginnt mit der Processing Instruction, welche die XML Version bekannt gibt, in welcher das Dokument verfasst wurde. Solche Instruktionen erkennt man am Fragezeichen zu Beginn und am Ende der Zeile.

Document Type (Zeile 2)

<!DOCTYPE order SYSTEM "Order.dtd" [
   <!ENTITY auml "&#228;">
]>

Der Document Type zeigt, dass eine Datei "Order.dtd" existiert, welche die Typendefinitionen enthält, "Order.dtd" wird im folgenden Abschnitt beschrieben. Mittels: auml "&#228;" wird der Umlaut ä definiert, dieser muss Teil des Unicode UTF-8 Zeichensatzes sein, den wir hier verwenden. Es existieren verschiedene Standards zur Zeichendarstellung, Unicode UTF-8 und UTF-16 werden am meisten verwendet. Wir verwenden im Beispiel hier nicht UTF-16, da dies von den heute zur Verfügung stehenden Browsern nicht unterstützt wird.

Body (Zeile 5)

<order>
   <!-- Auftragsnummer -->
   <id>74836647</id>

Nun beginnt die eigentliche Bestellung, nach dem Kommentar <!-- Auftragsnummer --> folgt 
die Auftragsnummer: 74836647 der Bestellung. Darauf folgen die zwei bestellten Artikel "Gehäuse" und "Kabelrolle".

Entity (Zeile 9)

<article>324-67511</article>

324-67511 wird als Character Data bezeichnet und stellt die Artikelnummer dar. <article> und </article> sind unsere Markup Tags, welche die Daten beschreiben. Einem Start Tag <article> muss immer ein End Tag </article> folgen. Ein einzelnes Tag muss mit einem Schrägstrich abgeschlossen werden, beispielsweise  <br/>.

Document Type Definition DTD

Das Datenmodell wird durch eine Document Type Definition DTD in der Datei "Order.dtd" beschrieben. Microsoft hat XML Schemas als neue Technologie eingeführt, dies soll aber an dieser Stelle wegen dem fehlenden Standard nicht verwendet werden.

Inhalt von "Order.dtd"

<!ELEMENT order (id, item+)+>
<!ELEMENT id (#PCDATA)>
<!ELEMENT item (article, name?, number+, (style | manufacturer*)+)>
<!ELEMENT article (#PCDATA)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT number (#PCDATA)>
<!ELEMENT style (#PCDATA)>
<!ELEMENT manufacturer (#PCDATA)>

Alle Elements sind als Parsed Character Data PCDATA deklariert. CDATA hingegen wird vom Parser nicht auf Tags untersucht. Auf die Häufigkeit und Existenz kann man Einfluss nehmen, wie Zeile 3 zeigt:

<!ELEMENT item (article, name?, number+, (style | manufacturer*)+)>

Ein nachgestelltes " ? " bestimmt, dass dieses Element genau einmal oder gar nicht vorhanden sein darf. Ein " + " dass dieses Element einmal oder mehrmals vorhanden sein muss. Ein " * " hingegen erlaubt eine beliebige Anzahl des Elements oder auch keines. Wird keines der beschriebenen Zeichen nachgestellt, so muss das Element genau einmal vorhanden sein. Mit " | " werden Elemente einer Liste getrennt, die zur Auswahl stehen.

Verarbeitung von XML mit einem Parser durch Oracle SAX API für Java

 Verwendet man XML in einem Programm, so spricht man von einer XML Application. Neben eigenen Applikationen sind Browser, welche die XML Darstellung unterstützen und XML Entwicklungswerkzeuge typische XML Applications. In allen Anwendungen findet ein XML Processor Verwendung. Seine Aufgabe ist es, Dokumente zu lesen, zu verarbeiten und zu schreiben. Ein XML Processor verwendet einen XML Parser, um die Struktur des Dokuments zu analysieren. Die Struktur muss konsequent eingehalten werden, dies garantiert eine hohe Parsing Qualität.

Es gibt verschiedene Möglichkeiten XML zu erzeugen und zu lesen, zwei davon sind das

  • Simple API for XML oder kurz SAX API

  • und das Document Object Model DOM.

In diesem Artikel soll eine einfache Möglichkeit mit Java und dem Oracle SAX API vorgestellt werden. Das SAX API ist weniger speicherintensiv dafür aber langsamer als DOM. Java findet in Applikationen immer mehr Verwendung und soll auch in unserem Beispiel benutzt werden.

Beispiel Kundenbestellung

In unserem Beispiel "Kundenbestellung" wird ein XML Parser im eigenen Java Code eingebettet. Sämtliche benötigten Komponenten sind nachfolgend aufgeführt.

Komponente Download Sites
min. JDK 1.1 http://java.sun.com/j2se/1.3/
XML Parser Java2 http://technet.us.oracle.com/software/index.htm
In der Auswahlliste kann der "XML Parser for Java v2" ausgewählt werden
https://www.akadia.com/download/soug/xml/xmlparser_v2_0_2_8.zip

Installation JDK 1.3

Der Download des JDK 1.3 ist sehr gross (30,916,766 Bytes), die Installation ist einfach und wird unter http://java.sun.com/j2se/1.3/install-windows.html detailliert beschrieben. Für unser Beispiel "Kundenbestellung" wurde JDK 1.3 unter D:\Jdk1.3 installiert. Dieser Pfad muss allenfalls für Ihr System angepasst werden.

Installation Oracle XML Parser Java

Der Download erfolgt direkt von Technet oder von unserer Site (siehe obige Links). Das ZIP-File wird beispielsweise in D:\XMLParser entpackt.

Parsen der Kundenbestellung

Die Datei "XMLParser.java" enthält den Java Code mit dem eingebetteten Oracle XML Parser. In unserem Beispiel wird die XML Datei "Order.xml" eingelesen, geparst und anschliessend werden diverse Status Meldungen ausgegeben. In einer konkreten Anwendung könnten die gelesenen Daten nun via JDBC in eine Bestellungsdatenbank geschrieben werden.

Code der Kundenbestellung: XMLParser.java

import java.io.*;
import java.net.*;
import org.xml.sax.*;
import oracle.xml.parser.v2.*;

/** Diese Klasse <code>XMLParser</code> ist von
    <code>HandlerBase</code> abgeleitet.
    <code>HandlerBase</code> implementiert die Interfaces
    <code>EntityResolver, DTDHandler, DocumentHandler, 
    ErrorHandler</code>. Es muessen hier nur die benötigten
    Methoden ueberschrieben werden.
    @author Rene Steiner, Akadia AG
*/

public class XMLParser extends HandlerBase
{
  // Locator speichern
  Locator locator;

  /** Hauptprogramm
      @param arguments Parameter die beim Programmstart
      uebergeben wurden
  */

  static public void main(String[] arguments) {
    try {
      // XML Dateiname muss beim Programmstart uebergeben werden
      if (arguments.length != 1) {
        System.err.println("Verwendung: XMLParser <Dateiname>");
        System.exit(1);
      }

      // Parser Handler erzeugen
      XMLParser  handler = new XMLParser ();

      // SAX Parser erzeugen
      Parser parser = new SAXParser();

      // Den Handler dem Parser zuordnen
      parser.setDocumentHandler(handler);
      parser.setEntityResolver(handler);
      parser.setDTDHandler(handler);
      parser.setErrorHandler(handler);

      // Dateiname in URL konvertieren und Parsing ausfuehren
      try {
        parser.parse(toURL(new File(arguments[0])).toString());
      }
      catch (SAXParseException ex) {
        System.err.println("XMLParser .main(): " 
        + ex.getMessage());
      }
      catch (SAXException ex) {
        System.err.println("XMLParser.main(): " 
        + ex.getMessage());
      }
    }
    catch (Exception ex) {
      System.err.println("XMLParser .main(): " 
      + ex.getMessage());
    }

  } // End of main()

  /** Diese Methode ist seit Java 2 in <code>java.io.File</code>
      vorhanden und muss hier nicht mehr implementiert werden.
      Wer Java 1 verwendet, kann jedoch diese benutzen.

      @see java.io.File#toURL
      @param file Datei Objekt mit der zu konvertierenden 
      Datei und Pfad
      @return URL
      @throws java.net.MalformedURLException
    */

  static URL toURL(File file) throws MalformedURLException {
    String path          = file.getAbsolutePath();
    String separator = System.getProperty("file.separator");

    if (separator != null && separator.length() == 1)
      path = path.replace(separator.charAt(0), '/');

    if (!path.startsWith("/"))
      path = "/" + path;

    if (!path.endsWith("/") && file.isDirectory())
      path = path + "/";

    return new URL("file", "", path);
  }

  // Es folgen die Methoden der verschiedenen Interfaces.
  // Diese werden aufgerufen, wenn der Parser die jeweiligen 
  // Elemente in der XML Datei findet.


  /** Interface DocumentHandler
  */

  public void setDocumentLocator(Locator locator) {
    System.out.println("setDocumentLocator");
    this.locator = locator;
  }

  /** Interface DocumentHandler
  */

  public void startDocument() {
    System.out.println("startDocument");
  }

  /** Interface DocumentHandler
  */

  public void endDocument() throws SAXException {
    System.out.println("endDocument");
  }

  /** Interface DocumentHandler
  */

  public void startElement(String name, AttributeList attributes)
              throws SAXException {
    System.out.println("startElement: " + name);

    for(int i = 0; i < attributes.getLength(); i++)
      System.out.println("->" + attributes.getName(i) + " " 
      + attributes.getType(i) + "=" + attributes.getValue(i));
  }

  /** Interface DocumentHandler
  */

  public void endElement(String name) throws SAXException {
    System.out.println("endElement: " + name);
  }

  /** Interface DocumentHandler
  */

  public void characters(char[] cbuf, int start, int len) {
    System.out.print("characters: ");
    System.out.println(new String(cbuf, start, len));
  }

  /** Interface DocumentHandler
  */

  public void ignorableWhitespace(char[] cbuf, int start, int len) {
    System.out.println("ignorableWhiteSpace");
  }

  /** Interface DocumentHandler
  */

  public void processingInstruction(String target, String data)
              throws SAXException {
    System.out.println("processingInstruction: " 
    + target + " " + data);
  }

  /** Interface EntityResolver
  */

  public InputSource resolveEntity(String publicId, String systemId)
         throws SAXException {
    System.out.println("resolveEntity: " 
    + (publicId != null ? publicId : "(no public id)") 
    + " " + systemId);
    System.out.println("locator: " + (locator.getPublicId() != null ?
    locator.getPublicId() : "(no public id)")
    + " " + locator.getSystemId() + " " + locator.getLineNumber() 
    + " " + locator.getColumnNumber());
    return null;
  }

  /** Interface DTDHandler
  */

  public void notationDecl(String name, String publicId, 
  String systemId) {
    System.out.println("notationDecl: " + name + " " 
    + publicId + " " + systemId);
  }

  /** Interface DTDHandler
  */

  public void unparsedEntityDecl(String name, 
         String publicId, String systemId, String notationName) {
    System.out.println("unparsedEntityDecl: " + name 
    + " " + publicId + " " + systemId + " " + notationName);
  }

  /** Interface ErrorHandler
   */

  public void warning (SAXParseException ex) throws SAXException {
    System.err.println("WARNING: " + ex.getMessage());
    throw new SAXException(ex);
  }

  /** Interface ErrorHandler
  */

  public void error(SAXParseException ex) throws SAXException {
    System.err.println("ERROR: " + ex.getMessage());
    throw new SAXException(ex);
  }

  /** Interface ErrorHandler
  */

  public void fatalError(SAXParseException ex) throws SAXException {
    System.err.println("FATALERROR: " + ex.getMessage());
    throw new SAXException(ex);
  }
} // End of class XMLParser 

Compilieren der Kundenbestellung mittels Batchdatei: compile.bat

D:\Jdk1.3\bin\javac -classpath ".;D:\Jdk1.3\src.jar; 
D:\XMLParser\lib\xmlparserv2.jar" XMLParser.java

Ausführen der Kundenbestellung mittels Batchdatei: run.bat

D:\Jdk1.3\bin\java -classpath ".;D:\Jdk1.3\jre\lib\rt.jar;
D:\XMLParser\lib\xmlparserv2.jar" XMLParser Order.xml

Output der Kundenbestellung

setDocumentLocator
startDocument
resolveEntity: (no public id) file:/C:/Users/Zahn/xml/src/sax/Order.dtd
locator: (no public id) file:/C:/Users/Zahn/xml/src/sax/Order.xml 4 3
startElement: order
ignorableWhiteSpace
ignorableWhiteSpace
startElement: id
characters: 74836647
endElement: id
ignorableWhiteSpace
startElement: item
ignorableWhiteSpace
startElement: article
characters: 324-67511
endElement: article
ignorableWhiteSpace
startElement: name
characters: Geh
characters: õ
characters: use
endElement: name
ignorableWhiteSpace
startElement: number
characters: 20
endElement: number
ignorableWhiteSpace
startElement: style
ignorableWhiteSpace
startElement: color
characters: rot
endElement: color
ignorableWhiteSpace
startElement: doors
characters: 2
endElement: doors
ignorableWhiteSpace
startElement: connectors
characters: 2
endElement: connectors
ignorableWhiteSpace
endElement: style
ignorableWhiteSpace
startElement: manufacturer
characters: Shelves
characters: &
characters:
characters: Cabinets Ltd.
endElement: manufacturer
ignorableWhiteSpace
endElement: item
ignorableWhiteSpace
startElement: item
ignorableWhiteSpace
startElement: article
characters: 655-01345
endElement: article
ignorableWhiteSpace
startElement: name
characters: Kabelrolle
endElement: name
ignorableWhiteSpace
startElement: number
characters: 10
endElement: number
ignorableWhiteSpace
startElement: style
ignorableWhiteSpace
startElement: color
characters: grau
endElement: color
ignorableWhiteSpace
startElement: width
characters: 300
endElement: width
ignorableWhiteSpace
endElement: style
ignorableWhiteSpace
startElement: manufacturer
characters: Kabel AG
endElement: manufacturer
ignorableWhiteSpace
endElement: item
ignorableWhiteSpace
endElement: order
endDocument

Darstellung von XML durch Cascading Style Sheets CSS
und eXtensible Style Language XSL

Möchte man XML Dokumente darstellen, so gibt es zwei Möglichkeiten:

  • Cascading Style Sheets CSS

  • oder eXtensible Style Language XSL

CSS kann sowohl für reine HTML- wie auch für XML-Dokumente verwendet werden. CSS wird heute von vielen Browsern unterstützt. XSL ist mächtiger und transformiert vor der Darstellung XML zu HTML. Es existieren programmähnliche Konstrukte wie Sortieren, Filtern und Suchen. Zur Zeit unterstützen Microsoft Internet Explorer 5 und Netscape Communicator 6 die Darstellung von XML. Die Darstellungsart und Qualität ist stark vom Browser abhängig.

Cascading Style Sheets CSS

Als erstes ein CSS Beispiel. Wir finden die einzelnen XML Entities wie beispielsweise id, item, article wieder. Dazu Informationen über die gewünschte Darstellung. Die XML-Datei "Order.xml" referenziert mittels href="Order.css" die CSS-Datei "Order.css". Klicken Sie hier, um die "Kundenbestellung" in ihrem Browser anzuzeigen.

Soll unsere "Kundenbestellung" mittels Cascading Style Sheets durch einen Browser angezeigt werden, so muss die folgende Zeile in der XML-Datei "Order.xml" hinzugefügt werden:

<?xml-stylesheet type="text/css" href="Order.css"?>

Datei "Order.css":

id {
  display: block;
  border-bottom: 5px solid silver;
  font-weight: bold;
}

item {
  display: block;
  width: 350px;
  border-bottom: 5px solid silver;
  color: blue;
  text-align: left;
}

article, name {
  display: inline;
  font-family: Times, serif;
  font-size: 16pt;
  font-weight: bold;
}

number, manufacturer {
  display: block;
  font-family: Times, serif;
  font-size: 13pt;
}

style {
  display: none;
}

eXtensible Style Language XSL

Bei XSL erscheinen HTML Tags, die zur Transformation notwendig sind.

Soll unsere "Kundenbestellung" mittels eXtensible Style Language XSL durch einen Browser angezeigt werden, so muss die folgende Zeile in der XML-Datei "Order.xml" hinzugefügt werden. Klicken Sie hier, um die "Kundenbestellung" in ihrem Browser anzuzeigen.

<?xml-stylesheet type="text/xsl" href="Order.xsl" ?>

Mit der Schleife <xsl:for-each select="order/item"> über alle Daten innerhalb order und item werden die Daten gelesen und mit  value-of select angesprochen. 

Durch XML Namespaces XMLNS können gleiche Bezeichner in verschiedenen Namespaces wiederverwendet werden. Wir benutzen hier die Standard Bezeichner aus dem XML Namespace. Die Browser kennen diesen URL und machen keinen Download von irgendwelchen Informationen. Als Bezeichner wählen wir xsl und referenzieren deshalb Tags über diesen Bezeichner <xsl:value-of select="number"/>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">

Datei "Order.xsl"

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">

  <xsl:template match="/">
    <html>
      <body bgcolor="white" fgcolor="blue">

      <strong><xsl:value-of select="order/id"/></strong>
      <hr size="5px" color="silver"/>

      <xsl:for-each select="order/item">
        <font face="Times, serif" size="5" color="blue"><strong>
          <br/><xsl:value-of select="article"/>
          <xsl:value-of select="name"/>
        </strong></font>
        <font face="Times, serif" size="4" color="blue">
          <br/><xsl:value-of select="number"/>
          <br/><xsl:value-of select="manufacturer"/>
        </font>
        <hr size="5px" width="350px" color="silver"/>
      </xsl:for-each>

      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

Ausblick

XML basiert auf einem einfachen Ansatz, ASCII Dateien mit Tags zu versehen. Die Tags haben eine bestimmte Bedeutung und können interpretiert werden. Die Interpretation wird sehr strikte gehandhabt und sollte frei von herstellerabhängigen Erweiterungen bleiben. Dies ermöglicht ein plattformunabhängiges Arbeiten und stärkt XML auf seinem Erfolgskurs. XML hat bereits eine breite Unterstützung von verschiedenen Herstellern erhalten, darunter auch Oracle. Es stehen eine grosse Anzahl verschiedenster Produkte zur Verfügung, welche bei der Entwicklung helfen und diese vereinfachen. Die vielen Zusatzprodukte machen XML zu einem mächtigen Werkzeug, welches zur Lösung verschiedenster Anwendungen herangezogen werden kann.

Links zu XML

Spezifikation und Standardisierung

www.w3.org/XML

XML Spezifikationen

www.w3.org/TR/1998/REC-xml-19980210

XML Standard

www.iso.ch

Standardisierung SGML

Tools und Libraries

technet.oracle.com/tech/xml

Oracle XML Developer's Kits

java.sun.com/xml/download.html

Sun Java API for XML Parsing

www.ibm.com/developer/xml

IBM XML Tools

xml.apache.org

Apache XML Project

java.sun.com/j2se

Java 2 (JDK 1.2 und 1.3)

java.sun.com/products/jdk/1.1

Java 1 (JDK 1.1.8)

Weitere Links und Software

www.oasis-open.org

Organization for the Advancement of Structured 
Information Standards

www.xmlsoftware.com

Unabhängige XML Quelle

www.gca.org

Graphic Communications Association

www.xml.com

Eine O'Reilly & Associates Tochterfirma

www.xml.com/axml/axml.html

Offizielle W3C Recommendation mit zusätzlichen 
Erklärungen versehen

www.xml.org

Unabhängiges, inoffizielles XML Portal

www.alphaworks.ibm.com

IBM XML Technologien

Weitere Informationen

René Steiner, Akadia AG, Arvenweg 4, CH-3604 Thun,
Tel: 033 3358622, E-Mail: rene.steiner@akadia.com