Reading and Writing XML Documents (C++)

www.altova.com このトピックを印刷 前のページ 1つ上のレベル 次のページ

ホーム >  ユーザーマニュアル > Code Generator > Generating Code from XML Schemas or DTDs > Example: Using the Schema Wrapper Libraries >

Reading and Writing XML Documents (C++)

After you generate code from the Library schema (see Example Schema), a test C++ application is created, along with several supporting Altova libraries.

 

 

About the generated C++ libraries

 

The following diagram illustrates some of the most important classes of the generated code.

 

cpp_class_diagram

 

The central class of the generated code is the CLibrary class, which represents the XML document. Such a class is generated for every schema and its name depends on the schema file name (Library.xsd, in this example). As shown in the diagram, this class provides methods for loading documents from files, binary streams, or strings (or saving documents to files, streams, strings). For a list of all members exposed by this class, see the class reference ( [YourSchema]::[CDoc] ).

 

The Library2 field of the CLibrary class represents the actual root of the document. The number at the end is meant to avoid a naming conflict with the class name. Library is an element in the XML file, so in the C++ code it has a template class as type (MemberElement). The template class exposes methods and properties for interacting with the Library element. In general, each attribute and each element of a type in the schema is typed in the generated code with the MemberAttribute and MemberElement template classes, respectively. For more information, see [YourSchema]::MemberAttribute and [YourSchema]::MemberElement class reference.

 

The class CLibraryType is generated from the schema complex type with the same name, as mentioned in About Schema Wrapper Libraries (C++).  Notice that the CLibraryType class contains a field Book, and a field LastUpdated. According to the logic already mentioned above, these correspond to the Book element and LastUpdated attribute in the schema, and enable you to manipulate programmatically (append, remove, etc) elements and attributes in the instance XML document.

 

Since the DictionaryType is a complex type derived from BookType in the schema, this relationship is also reflected in the generated classes. As illustrated in the diagram, the class CDictionaryType inherits the CBookType class.

 

If your XML schema defines simple types as enumerations, the enumerated values become available as Enum values in the generated code. In the schema used in this example, a book format can be hardcover, paperback, e-book, and so on. Therefore, in the generated code, these values would be available through an Enum that is a member of the CBookFormatType class.

 

 

Writing an XML document

 

1.Open the LibraryTest.sln solution in Visual Studio generated from the Library schema mentioned earlier in this example.

 

While prototyping an application from a frequently changing XML schema, you may need to frequently generate code to the same directory, so that the schema changes are immediately reflected in the code. Note that the generated test application and the Altova libraries are overwritten every time when you generate code into the same target directory. Therefore do not add code to the generated test application. Instead, integrate the Altova libraries into your project (see Integrating Schema Wrapper Libraries).

 

2.In Solution Explorer, open the LibraryTest.cpp file, and edit the Example() method as shown below.

 

#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.Press F5 to start debugging. If the code was executed successfully, a GeneratedLibrary.xml file is created in the solution output directory.

 

 

Reading an XML document

 

1.Open the LibraryTest.sln solution in Visual Studio.
2.Save the code below as Library1.xml to a directory that can be read by the program code (for example, the same directory as 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.In Solution Explorer, open the LibraryTest.cpp file, and edit the Example() method as shown below.

 

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.Press F5 to start debugging.

(C) 2018 Altova GmbH