Altova XMLSpy 2024 Enterprise Edition

After you generate code from the example schema, a test C++ application is created, along with several supporting Altova libraries.

 

About the generated C++ libraries

The central class of the generated code is the CDoc class, which represents the XML document. Such a class is generated for every schema and its name depends on the schema file name. 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 description of all members exposed by this class, see the class reference ([YourSchema]::[CDoc]).

cg_cpp_example_01

The Library field of the CDoc class represents the actual root of the document. 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 LibraryType complex type in the schema. Notice that the CLibraryType class contains two fields: Book and 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.

cg_cpp_example_02

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

cg_cpp_example_03

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 Doc; // required to work with Altova libraries
 
void Example()
{
  // Create a new, empty XML document
  CDoc libDoc = CDoc::CreateDocument();
 
  // Create the root element <Library> and add it to the document
  CLibraryType lib = libDoc.Library.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 Doc;
void Example()
{
  // Load XML document
  CDoc libDoc = CDoc::LoadFromFile(_T("Library1.xml"));
 
  // Get the first (and only) root element <Library>
  CLibraryType lib = libDoc.Library.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.

© 2017-2023 Altova GmbH