从示例Schema生成代码后,将生成一个测试C++应用程序以及多个支持的Altova库。
关于生成的C++库
生成的代码的中心类是CDoc类,它表示XML文档。为每个Schema生成这样的类,其名称取决于Schema文件名。如图所示,此类提供了从文件、二进制流或字符串中加载文档(或将文档保存到文件、流和字符串)的方法。有关此类提供的所有成员的说明,请参见类引用([YourSchema]::[CDoc])。
CDoc类的Library字段表示文档的实际根。Library是XML文件中的一个元素,因此在C++代码中它有一个模板类作为其类型(MemberElement)。模板类提供与Library元素交互的方法和属性。通常,Schema中特定类型的每个特性和元素都在生成的代码中分别被赋予MemberAttribute和MemberElement模板类。有关更多信息,请参见[YourSchema]::MemberAttribute和[YourSchema]::MemberElement类引用。
CLibraryType类的从Schema中的LibraryType复杂类型生成的。请注意,CLibraryType类包含两个字段:Book和LastUpdated。根据上述的逻辑,这些分别对应于Schema中的Book元素和LastUpdated特性。它们允许您对XML实例文档中的元素和特性进行编程操作(追加、删除等)。
DictionaryType是一个复杂类型,从Schema中的BookType派生,因此这一关系也反映在生成的类中。如图所示,CDictionaryType类继承了CBookType类。
如果简单类型在您的XML Schema中定义为枚举,则枚举值将在生成的代码中作为enum值可用。在本例使用的Schema中,有精装、平装、电子书等图书格式。因此,在生成的代码中,这些值以enum的形式提供,即作为CBookFormatType类的成员。
编写XML文档
1.在Visual Studio中打开从“库”Schema生成的LibraryTest.sln解决方案。
在根据频繁更改的XML Schema对应用程序进行原型设计时,您可能需要频繁地将代码生成到同一目录,从而将Schema更改及时反映在代码中。请注意,每次将代码生成到同一个目标目录中时,都会覆盖生成的测试应用程序和Altova库。因此,不能将代码添加到生成的测试应用程序中。取而代之的是,将Altova库集成到您的项目中(参见集成Schema包装库)。 |
2.在解决方案资源管理器中打开LibraryTest.cpp文件,并编辑Example()方法,如下所示。
#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.按F5开始调试。如果成功运行代码,则会在解决方案输出目录中创建GeneratedLibrary.xml文件。
读取XML文档
1.在Visual Studio中打开LibraryTest.sln解决方案。
2.将下方代码以Library1.xml形式保存到可以通过程序代码读取的目录下(例如,与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.在解决方案资源管理器中打开LibraryTest.cpp文件,并编辑Example()方法,如下所示。
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.按F5开始调试。