Altova MapForce 2024 Enterprise Edition

Nachdem Sie anhand des Schemas "Library" (siehe Beispielschema) Code generiert haben, wird eine C#-Testapplikation sowie eine Reihe von unterstützenden Altova-Bibliotheken generiert.

 

Informationen zu den generierten C#-Bibliotheken

Die zentrale Klasse des generierten Codes ist die Klasse Doc2. Sie repräsentiert das XML-Dokument. Eine solche Klasse wird für jedes Schema generiert. Ihr Name hängt vom Namen der Schemadatei ab. Beachten Sie, dass diese Klasse den Namen Doc2 erhält, um einen möglichen Konflikt mit dem Namespace-Namen zu vermeiden. Wie im Diagramm gezeigt, bietet diese Klasse Methoden zum Laden von Dokumenten aus Dateien, Binär-Streams oder Strings (oder zum Speichern von Dokumenten in Dateien, Streams, Strings). In der Referenz zur Klasse ([YourSchema].[Doc] ) finden Sie eine Beschreibung dieser Klasse.

cg_cs_example_01

Der Member Library der Klasse Doc2 stellt die eigentliche Root des Dokuments dar.

 

Gemäß den im Kapitel Informationen zu Schema Wrapper-Bibliotheken (C#) angeführten Codegenerierungsregeln werden für jedes Attribut und jedes Element eines Typs Member-Klassen generiert. Der Name solcher Member-Klassen erhält im generierten Code das Präfix MemberAttribute_ bzw. MemberElement_. Beispiele für solche Klassen sind MemberAttribute_ID und MemberElement_Author, die anhand des Elements Author bzw. des Attributs ID eines Buchs generiert wurden (Im Diagramm unten sind dies unter BookType verschachtelte Klassen). Sie ermöglichen die programmatische Bearbeitung (z.B. Anhängen, Entfernen, Wert definieren, usw.) der entsprechenden Elemente und Attribute im XML-Instanzdokument. Nähere Informationen dazu finden Sie in der Referenz zur Klasse unter [YourSchemaType].MemberAttribute und [YourSchemaType].MemberElement.

 

Der Typ DictionaryType ist ein complexType, der im Schema von BookType abgeleitet wurde, daher wird diese Beziehung auch in den generierten Klassen übernommen. Im Diagramm unten sehen Sie, dass die Klasse DictionaryType die Klasse BookType erbt.

cg_cs_example_02

Wenn in Ihrem XML-Schema simpleTypes als Enumerationen definiert sind, so stehen die enumerierten Werte im generierten Code als Enum-Werte zur Verfügung. In dem in diesem Beispiel verwendeten Schema gibt es die Buchformate hardcover, paperback, e-book, usw. Im generierten Code stehen diese Werte folglich in Form einer Enum, d.h. als Member der Klasse CBookFormatType, zur Verfügung.

 

Schreiben eines XML-Dokuments

1.Öffnen Sie die anhand des Schemas "Library" generierte Lösung LibraryTest.sln in Visual Studio.

 

Beim Erstellen eines Prototyps einer Applikation anhand eines häufig geänderten XML-Schemas müssen Sie eventuell immer wieder Code im selben Verzeichnis generieren, damit die Änderungen am Schema sofort im Code berücksichtigt werden. Beachten Sie, dass die generierte Testapplikation und die Altova-Bibliotheken jedes Mal, wenn Sie Code im selben Zielverzeichnis generieren, überschrieben werden. Fügen Sie daher keinen Code zur generierten Testapplikation hinzu, sondern integrieren Sie stattdessen die Altova-Bibliotheken in Ihr Projekt (siehe Integrieren von Schema Wrapper-Bibliotheken).

 

2.Öffnen Sie die Datei LibraryTest.cs im Solution Explorer und bearbeiten Sie die Methode Example() wie unten gezeigt.

 

protected static void Example()
{
  // Create a new XML document
  Doc2 doc = Doc2.CreateDocument();
  // Append the root element
  LibraryType root = doc.Library.Append();
 
  // Create the generation date using Altova DateTime class
  Altova.Types.DateTime dt = new Altova.Types.DateTime(System.DateTime.Now);
  // Append the date to the root
  root.LastUpdated.Value = dt;
 
  // Add a new book
  BookType book = root.Book.Append();
  // Set the value of the ID attribute
  book.ID.Value = 1;
  // Set the format of the book (enumeration)
  book.Format.EnumerationValue = BookFormatType.EnumValues.eHardcover;
  // Set the Title and Author elements
  book.Title.Append().Value = "The XMLSpy Handbook";
  book.Author.Append().Value = "Altova";
 
  // Append a dictionary (book of derived type) and populate its attributes and elements
  DictionaryType dictionary = new DictionaryType(root.Book.Append().Node);
  dictionary.ID.Value = 2;
  dictionary.Title.Append().Value = "English-German Dictionary";
  dictionary.Format.EnumerationValue = BookFormatType.EnumValues.eE_book;
  dictionary.Author.Append().Value = "John Doe";
  dictionary.FromLang.Append().Value = "English";
  dictionary.ToLang.Append().Value = "German";
  // Since it's a derived type, make sure to set the xsi:type attribute of the book element
  dictionary.SetXsiType();
 
  // Optionally, set the schema location (adjust the path if
  // your schema is not in the same folder as the generated instance file)
  doc.SetSchemaLocation("Library.xsd");
 
  // Save the XML document with the "pretty print" option enabled
  doc.SaveToFile("GeneratedLibrary.xml", true);
}

 

3.Drücken Sie F5, um den Debugger zu starten. Wenn der Code erfolgreich ausgeführt wurde, wird im Lösungsausgabeverzeichnis (normalerweise bin/Debug) die Datei GeneratedLibrary.xml erstellt.

 

Lesen eines XML-Dokuments

1.Öffnen Sie die Lösung LibraryTest.sln in Visual Studio.

2.Speichern Sie den unten gezeigten Code unter dem Namen Library.xml im Ausgabeverzeichnis (standardmäßig bin/Debug). Dies ist die Datei, die vom Programmcode gelesen wird.

 

<?xml version="1.0" encoding="utf-8"?>
<Library xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.nanonull.com/LibrarySample" xsi:schemaLocation="http://www.nanonull.com/LibrarySample Library.xsd" LastUpdated="2016-02-03T17:10:08.4977404">  
  <Book ID="1" Format="E-book">
    <Title>The XMLSpy Handbook</Title>
    <Author>Altova</Author>      
  </Book>
  <Book ID="2" Format="Paperback" xmlns:n1="http://www.nanonull.com/LibrarySample" xsi:type="n1:DictionaryType">
    <Title>English-German Dictionary</Title>
    <Author>John Doe</Author>
    <FromLang>English</FromLang>
    <ToLang>German</ToLang>
  </Book>
</Library>

 

3.Öffnen Sie die Datei LibraryTest.cs im Solution Explorer und bearbeiten Sie die Methode Example() wie unten gezeigt.

 

protected static void Example()
{
  // Load the XML file
  Doc2 doc = Doc2.LoadFromFile("Library.xml");
  // Get the root element
  LibraryType root = doc.Library.First;
 
  // Read the library generation date
  Altova.Types.DateTime dt = root.LastUpdated.Value;
  string dt_as_string = dt.ToString(DateTimeFormat.W3_dateTime);
  Console.WriteLine("The library generation date is: " + dt_as_string);
 
  // Iteration: for each <Book>...
  foreach (BookType book in root.Book)
  {
    // Output values of ID attribute and (first and only) title element
    Console.WriteLine("ID:    " + book.ID.Value);
    Console.WriteLine("Title: " + book.Title.First.Value);
 
    // Read and compare an enumeration value
    if (book.Format.EnumerationValue == BookFormatType.EnumValues.ePaperback)
        Console.WriteLine("This is a paperback book.");
 
    // Iteration: for each <Author>
    foreach (xs.stringType author in book.Author)
        Console.WriteLine("Author: " + author.Value);
 
    // Determine if this book is of derived type      
    if (book.Node.Attributes.GetNamedItem("xsi:type") != null)
    {
        // Find the value of the xsi:type attribute
        string xsiTypeValue = book.Node.Attributes.GetNamedItem("xsi:type").Value;
        // Get the namespace URI and the lookup prefix of this namespace
        string namespaceUri = book.Node.NamespaceURI;
        string prefix = book.Node.GetPrefixOfNamespace(namespaceUri);
 
        // if this book has DictionaryType
        if (namespaceUri == "http://www.nanonull.com/LibrarySample" && xsiTypeValue.Equals(prefix + ":DictionaryType"))
        {
          // output additional fields
          DictionaryType dictionary = new DictionaryType(book.Node);
          Console.WriteLine("Language from: " + dictionary.FromLang.First.Value);
          Console.WriteLine("Language to: " + dictionary.ToLang.First.Value);
        }
        else
        {
          throw new Exception("Unexpected book type");
        }
    }
  }
 
  Console.ReadLine();
}

 

4.Drücken Sie F5, um den Debugger zu starten. Wenn der Code erfolgreich ausgeführt wurde, wird Library.xml vom Programmcode gelesen und ihr Inhalt wird als Konsolenausgabe angezeigt.

 

Lesen und Schreiben von Elemente und Attributen

Die Werte von Attributen und Elementen können über die Eigenschaft Value der generierten Member-Element- bzw. Attribut-Klasse gelesen werden, z.B.:

 

// output values of ID attribute and (first and only) title element
System.out.println("ID:    " + book.ID.Value);
Console.WriteLine("Title: " + book.Title.First.Value);

 

Um in diesem konkreten Beispiel den Wert des Elements Title abzurufen, haben wir auch die Methode First() verwendet, da es sich hier um des erste (und einzige) Title-Element eines Buchs handelt. In Fällen, in denen ein bestimmtes Element nach dem Index aus einer Liste gewählt werden soll, verwenden Sie die Methode At().

 

Die für die einzelnen Member-Elemente eines Typs generierte Klasse implementiert die Standardschnittstelle System.Collections.IEnumerable. Auf diese Art können mehrere Elemente desselben Typs in einer Schleife verarbeitet werden. In diesem konkreten Beispiel können Sie alle Bücher eines Library-Objekts folgendermaßen in einer Schleife verarbeiten:

 

// Iteration: for each <Book>...
foreach (BookType book in root.Book)
{
  // your code here...              
}

 

Mit Hilfe der Methode Append()können Sie ein neues Element hinzufügen. Im folgenden Code wird z.B. das Root-Element an das Dokument angehängt:

 

// Append the root element to the library
LibraryType root = doc.Library.Append();

 

Sie können den Wert eines Attributs (wie ID in diesem Beispiel) folgendermaßen definieren:

 

// Set the value of the ID attribute
book.ID.Value = 1;

 

Lesen und Schreiben von Enumerationswerten

Wenn in Ihrem XML-Schema simpleTypes als Enumerationen definiert sind, so stehen die enumerierten Werte im generierten Code als Enum-Werte zur Verfügung. In dem in diesem Beispiel verwendeten Schema gibt es die Buchformate hardcover, paperback, e-book, usw. Im generierten Code stehen diese Werte folglich in Form einer Enum zur Verfügung.

ex_class_BookFormatType

Mit Hilfe von Code wie dem unten gezeigten können Sie einem Objekt Enumerationswerte zuweisen:

 

// Set the format of the book (enumeration)
book.Format.EnumerationValue = BookFormatType.EnumValues.eHardcover;

 

Solche Enumerationswerte können folgendermaßen aus XML-Instanzdokumenten ausgelesen werden:

 

// Read and compare an enumeration value
if (book.Format.EnumerationValue == BookFormatType.EnumValues.ePaperback)
Console.WriteLine("This is a paperback book.");

 

Wenn eine "if"-Bedingung nicht genügt, erstellen Sie einen Switch, um jeden Enumerationswert zu ermitteln und wie erforderlich zu verarbeiten.

 

Arbeiten mit den Typen xs:dateTime und xs:duration

Wenn im Schema, anhand dessen Sie Code generiert haben, Uhrzeit- und Zeitdauer-Typen wie xs:dateTime oder xs:duration vorkommen, so werden diese im generierten Code in native Altova-Klassen konvertiert. Gehen Sie daher folgendermaßen vor, um einen Datums- oder Zeitdauerwert in das XML-Dokument zu schreiben:

 

1.Erstellen Sie ein Altova.Types.DateTime- oder Altova.Types.Duration-Objekt (entweder anhand von System.DateTime oder durch Verwendung von Teilen wie Stunden und Minuten; nähere Informationen siehe Altova.Types.DateTime und Altova.Types.Duration).

2.Definieren Sie das Objekt als Wert des benötigten Elements oder Attributs, z.B.:

 

// Create the library generation date using Altova DateTime class
Altova.Types.DateTime dt = new Altova.Types.DateTime(System.DateTime.Now);
// Append the date to the root
root.LastUpdated.Value = dt;

 

Um ein Datum oder eine Zeitdauer aus einem XML-Dokument zu lesen, gehen Sie folgendermaßen vor:

 

1.Deklarieren Sie den Elementwert (oder den Attributwert) als Altova.Types.DateTime- oder Altova.Types.Duration-Objekt.

2.Formatieren Sie das benötige Element oder Attribut, z.B.:

 

// Read the library generation date
Altova.Types.DateTime dt = root.LastUpdated.Value;
string dt_as_string = dt.ToString(DateTimeFormat.W3_dateTime);
Console.WriteLine("The library generation date is: " + dt_as_string);

 

Nähere Informationen dazu finde Sie in der Referenz zu den Klassen Altova.Types.DateTime und Altova.Types.Duration.

 

Arbeiten mit abgeleiteten Typen

Wenn in Ihrem XML-Schema abgeleitete Typen (derived types) definiert sind, so können Sie die Typableitung in programmatisch erstellten oder geladenen XML-Dokumenten beibehalten. Im folgenden Codefragment wird gezeigt, wie Sie anhand des in diesem Beispiel verwendeten Schemas ein neues Buch mit dem abgeleiteten Typ DictionaryType erstellen.

 

// Append a dictionary (book of derived type) and populate its attributes and elements
DictionaryType dictionary = new DictionaryType(root.Book.Append().Node);
dictionary.ID.Value = 2;
dictionary.Title.Append().Value = "English-German Dictionary";
dictionary.Author.Append().Value = "John Doe";
dictionary.FromLanguage.Append().Value = "English";
dictionary.ToLanguage.Append().Value = "German";
 
// Since it's a derived type, make sure to set the xsi:type attribute of the book element
dictionary.SetXsiType();

 

Beachten Sie, dass es wichtig ist, dass Sie das xsi:type Attribut des neu erstellten Buchs definieren. Damit stellen Sie sicher, dass der Buchtyp korrekt vom Schema interpretiert wird, wenn das XML-Dokument validiert wird.

 

Im folgenden Codefragment gezeigt, wie ein Buch vom abgeleiteten Typ DictionaryType in der geladenen XML-Instanz identifiziert wird, wenn Sie Daten aus einem XML-Dokument laden. Zuerst wird im Code der Wert des xsi:type-Attributs des Buchs gefunden. Wenn die Namespace URI dieses Node http://www.nanonull.com/LibrarySample lautet und wenn das URI-Lookup-Präfix und der Typ mit dem Wert des xsi:type-Attributs übereinstimmen, so handelt es sich um ein Wörterbuch:

 

    // Determine if this book is of derived type              
    if (book.Node.Attributes.GetNamedItem("xsi:type") != null)
    {
        // Find the value of the xsi:type attribute
        string xsiTypeValue = book.Node.Attributes.GetNamedItem("xsi:type").Value;
        // Get the namespace URI and the lookup prefix of this namespace
        string namespaceUri = book.Node.NamespaceURI;
        string prefix = book.Node.GetPrefixOfNamespace(namespaceUri);
 
        // if this book has DictionaryType
        if (namespaceUri == "http://www.nanonull.com/LibrarySample" && xsiTypeValue.Equals(prefix + ":DictionaryType"))
        {
            // output additional fields
            DictionaryType dictionary = new DictionaryType(book.Node);
            Console.WriteLine("Language from: " + dictionary.FromLang.First.Value);
            Console.WriteLine("Language to: " + dictionary.ToLang.First.Value);
        }
        else
        {
            throw new Exception("Unexpected book type");
        }
    }

© 2017-2023 Altova GmbH