Lesen und Schreiben von XML-Dokumenten (C++)

www.altova.com Dieses Kapitel drucken Vorherige Seite Eine Ebene nach oben Nächste Seite

Startseite >  Benutzerhandbuch und Referenz > Code Generator > Generieren von Code anhand von XML-Schemas oder DTDs > Beispiel: Verwendung der Schema Wrapper-Bibliotheken >

Lesen und Schreiben von XML-Dokumenten (C++)

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

Im folgenden Diagramm sehen Sie einige der wichtigsten Klassen des generierten Codes.

 

cpp_class_diagram

 

Die zentrale Klasse des generierten Codes ist die Klasse CLibrary. Sie repräsentiert das XML-Dokument. Eine solche Klasse wird für jedes Schema generiert. Ihr Name hängt vom Namen der Schemadatei ab (in diesem Beispiel Library.xsd). 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]::[CDoc]) finden Sie eine Liste aller von dieser Klasse bereitgestellten Members.

 

Das Feld Library2 der Klasse CLibrary stellt die eigentliche Root des Dokuments dar. Die Zahl am Ende dient dazu, einen Namenskonflikt mit dem Klassennamen zu vermeiden. Library ist ein Element in der XML-Datei, daher hat es im C++-Code eine Vorlagenklasse als Typ (MemberElement). Die Vorlagenklasse stellt Methoden und Eigenschaften für die Interaktion mit dem Element Library bereit. Im Allgemeinen erhält jedes Attribut und jedes Element eines bestimmten Typs im Schema im generierten Code die Vorlagenklasse MemberAttribute bzw. MemberElement. Nähere Informationen dazu finden Sie in der Referenz zur Klasse unter [YourSchema]::MemberAttribute und [YourSchema]::MemberElement.

 

Die Klasse CLibraryType wird anhand des gleichnamigen complexType im Schema generiert (siehe Informationen zu Schema Wrapper-Bibliotheken (C++). Beachten Sie, dass die Klasse CLibraryType ein Feld Book und ein Feld LastUpdated enthält. Gemäß der oben erwähnten Logik entsprechen diese dem Element Book und dem Attribut LastUpdated im Schema. Sie ermöglichen die programmatische Bearbeitung (Anhängen, Entfernen, usw.) von Elementen und Attributen im XML-Instanzdokument.

 

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

 

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.cpp im Solution Explorer und bearbeiten Sie die Methode Example() wie unten gezeigt.

 

#include <ctime> // required to get current time

using namespace Library; // required to work with Altova libraries

 

void Example()

{

 // Create a new, empty XML document

 CLibrary libDoc = CLibrary::CreateDocument();

 

 // Create the root element <Library> and add it to the document

 CLibraryType lib = libDoc.Library2.append();

 

 // Get current time and set the "LastUpdated" attribute using Altova classes

 time_t t = time(NULL);        

 struct tm * now = localtime( & t );

 altova::DateTime dt = altova::DateTime(now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec);

 lib.LastUpdated = dt;

 

 // Create a new <Book> and add it to the library

 CBookType book = lib.Book.append();

 

 // Set the "ID" attribute of the book

 book.ID = 1;

 

 // Set the "Format" attribute of the <Book> using an enumeration constant

 book.Format.SetEnumerationValue( CBookFormatType::k_Paperback );

 

 // Add the <Title> and <Author> elements, and set values

 book.Title.append() = _T("The XML Spy Handbook");

 book.Author.append() = _T("Altova");

 

 // Append a dictionary (book of derived type) and populate its attributes and elements

 CDictionaryType dictionary = CDictionaryType(lib.Book.append().GetNode());

 dictionary.ID = 2;

 dictionary.Format.SetEnumerationValue( CBookFormatType::k_E_book);

 dictionary.Title.append() = _T("English-German Dictionary");

 dictionary.Author.append() = _T("John Doe");

 dictionary.FromLang.append() = _T("English");

 dictionary.ToLang.append() = _T("German");

 

 // Since dictionary a derived type, set the xsi:type attribute of the book element

 dictionary.SetXsiType();

 

 // Optionally, set the schema location

 libDoc.SetSchemaLocation(_T("Library.xsd"));

 

 // Save the XML document to a file with default encoding (UTF-8),

 // "true" causes the file to be pretty-printed.

 libDoc.SaveToFile(_T("GeneratedLibrary.xml"), true);

 

 // Destroy the document

 libDoc.DestroyDocument();

}

 

3.Drücken Sie F5, um den Debugger zu starten. Wenn der Code erfolgreich ausgeführt wurde, wird im Lösungsausgabeverzeichnis 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 Library1.xml in einem Verzeichnis, das vom Programmcode gelesen werden kann (z.B im selben Verzeichnis wie LibraryTest.sln).

 

<?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.cpp im Solution Explorer und bearbeiten Sie die Methode Example() wie unten gezeigt.

 

using namespace Library;

void Example()

{

 // Load XML document

 CLibrary libDoc = CLibrary::LoadFromFile(_T("Library1.xml"));

 

 // Get the first (and only) root element <Library>

 CLibraryType lib = libDoc.Library2.first();

 

 // Check whether an element exists:

 if (!lib.Book.exists())

 {

         tcout << "This library is empty." << std::endl;

         return;

 }

 

 // iteration: for each <Book>...

 for (Iterator<CBookType> itBook = lib.Book.all(); itBook; ++itBook)

 {

         // output values of ISBN attribute and (first and only) title element

         tcout << "ID: " << itBook->ID << std::endl;

         tcout << "Title: " << tstring(itBook->Title.first()) << std::endl;

         

         // read and compare an enumeration value

         if (itBook->Format.GetEnumerationValue() == CBookFormatType::k_Paperback)

                 tcout << "This is a paperback book." << std::endl;

         

         // for each <Author>...

         for (CBookType::Author::iterator itAuthor = itBook->Author.all(); itAuthor; ++itAuthor)

                 tcout << "Author: " << tstring(itAuthor) << std::endl;

         

         // alternative: use count and index

         for (unsigned int j = 0; j < itBook->Author.count(); ++j)

                 tcout << "Author: " << tstring(itBook->Author[j]) << std::endl;

 }

 

 // Destroy the document

 libDoc.DestroyDocument();

}

 

4.Drücken Sie F5, um den Debugger zu starten.

© 2019 Altova GmbH