XBinder

XML 到代码生成工具

有效的、低成本的XML数据绑定加速您的项目推向市场的时间

从XML schema而来的生成构造良好的、可信赖的类库的复杂性,可以挑战任何项目的时间线和员工生产力。 XBinder XML 到 C / C++数据绑定工具充分流线化和简化了项目的开发维护时间,自动地串行化对象到XML和 反串行化XML到C或者C++对象。


为什么需要使用XML数据绑定或XML到代码的生成工具?

XBinder的XML数据绑定提供了如下超过传统XML API如SAX和DOM的优势:

性能 - 诸如验证或序列化操作通常用从XML生 成的代码比用验证解析器更快。原因是编译时做决策并直接生成代码,而为了做决策验证解析器要加载并使用 一个运行描述结构。

易用 - XBinder自动产生良好结构的、易于阅读的代码,加快推向市场的周期。

可靠 - XXML数据绑定应用程序通过在架构层次上工作,确保所生成的XML文档的正确性。

XBinder概览

XBinder是一个XML架构到C/C++, Java, 或C#数据的生成工具。XML数据绑定(或代码生成)是一个把XML描述信息项转换成计算机语言中的类型定义和函数的过程。

XBinder编译器产生的源代码是由类型定义和编码/解码函数组成的C, C++, Java, 或 C# 源代码。为使用所有在XML规范内包 含的消息定义提供了完整的应用程序接口(API)。

除了编译器,一个公用编码/解码函数的运行库也是该软件包的一部分。该函数库含有编码和解码的基本XML简单类 型(整数,字符串,十六二进制,等)例程。XBinder代码生成工具组合了一系列函数调用,以实现更复杂消息类型的编 码和解码。

评估版本可用于 Windows, Linux, 各种 UNIX 平台, 以及 Apple Mac OSX.

假设你需要编写代码来解析下面的XML实例,并打印出所有的包含在其中的数据。


        <purchase>
        <customer number="12345">
        John Smith
        </customer>
        <store>
        Toys R Us
        </store>
        <item>
        Rubber Ducky Bath Set
        </item>
        <price>
        19.95
        </price>
        </purchase>
      

在本页中,我们将比较不使用XBinder来解析此实例的必要的代码数量,与使用XBinder来解析此实例的必要的代码数量。 在两个例子中我们都将使用C++。对于非XBinder代码,我们将使用的libxml++的DOM功能。

下面是如果不使用XBinder,将需要编写的代码:

      
       #include <libxml++/libxml++.h>
       #include <stdio.h>

       int main()
       {
       // Parse the XML file.
       xmlpp::DomParser parser;
       parser.set_substitute_entities();
       try
       {
       parser.parse_file("purchase.xml");
       }
       catch (std::exception& ex)
       {
       printf("\n%s", ex.what());
       }

       // Get the root node.
       xmlpp::Node* pPurchaseNode = parser.get_document()->get_root_node();
       Glib::ustring nodename = pPurchaseNode->get_name();

       // Get the root node's children in a list.
       xmlpp::Node::NodeList purchaseChildren = pPurchaseNode->get_children();

       // Now walk through the children and process them according to what element
       // is represented.
       for (xmlpp::Node::NodeList::iterator iter = purchaseChildren.begin();
       iter != purchaseChildren.end(); ++iter)
       {
       xmlpp::Node* pChildNode = *iter;
       nodename = pChildNode->get_name();

       if (nodename == "text")
       {
       // We'll get the text value for each element explicitly
       // as we encounter them.
       continue;
       }
       else if (nodename == "customer")
       {
       // We're at the <customer> node.  We want to print the customer number
       // and the customer name.
       xmlpp::Element* pChildElement = dynamic_cast<xmlpp::Element*> (pChildNode);
       xmlpp::Attribute* pCustomerAttr = pChildElement->get_attribute("number");
       printf("\nCustomer number:  %s", pCustomerAttr->get_value().c_str());

       xmlpp::TextNode* pChildText = pChildElement->get_child_text();
       printf("\nCustomer name:  %s", pChildText->get_content().c_str());
       }
       else if (nodename == "store")
       {
       // We're at the <store> node.  We want to print the store name.
       xmlpp::Element* pChildElement = dynamic_cast<xmlpp::Element*> (pChildNode);
       xmlpp::TextNode* pChildText = pChildElement->get_child_text();
       printf("\nStore name:  %s", pChildText->get_content().c_str());
       }
       else if (nodename == "item")
       {
       // We're at the <item> node.  We want to print the item name.
       xmlpp::Element* pChildElement = dynamic_cast<xmlpp::Element*> (pChildNode);
       xmlpp::TextNode* pChildText = pChildElement->get_child_text();
       printf("\nItem name:  %s", pChildText->get_content().c_str());
       }
       else if (nodename == "price")
       {
       // We're at the <price> node.  We want to print the price.
       xmlpp::Element* pChildElement = dynamic_cast<xmlpp::Element*> (pChildNode);
       xmlpp::TextNode* pChildText = pChildElement->get_child_text();
       printf("\nPrice:  %s", pChildText->get_content().c_str());
       }
       }

       return 0;
       }
     
   

以下是使用XBinder,将需要编写的代码:

      
       #include "rtxsrc/OSRTFileInputStream.h"
       #include "rtxmlsrc/rtXmlCppMsgBuf.h"
       #include <Purchase.h>
       #include <stdio.h>

       int main()
       {
       // Setup to decode the instance in purchase.xml
       int stat;
       char* filename = "Purchase.xml";
       OSRTFileInputStream in (filename);
       OSXMLDecodeBuffer decodeBuffer (in);
       purchase_CC pdu (decodeBuffer);

       // Do the decode
       stat = pdu.decode();

       // Print the information that was in the instance.
       PurchaseRecord* pPurchase = pdu.getValue();
       printf("\nCustomer number:  %d", pPurchase->customer.number);
       printf("\nCustomer name:  %s", pPurchase->customer.value.c_str());
       printf("\nStore name:  %s", pPurchase->store.c_str());
       PurchaseRecord_3* pItemAndPrice = pPurchase->_seq3.getItem(0);
       unsigned short i = 0;
       while (pItemAndPrice != 0)
       {
       printf("\nItem name:  %s", pItemAndPrice->item.c_str());
       printf("\nItem price:  %.2f", pItemAndPrice->price);
       pItemAndPrice = pPurchase->_seq3.getItem(++i);
       }
       return stat;
       }
     
   

关于这些示例代码的一些内容是值得注意的:

  • 不使用XBinder的代码是大约使用它的代码的两倍。
  • 使用XBinder会减少代码编写者必须具备的关于XML实例结构的知识量。对于这个简单的实例, 代码编写者如果使用XBinder,几乎不需要XML结构知识。
  • 不使用XBinder的代码没有做XML语法的任何验证。例如,如果与该实例关联的架构规定<store> 元素必须紧跟<customer> 元素, 此约束得不到检查。添加此类型检查会使得非XBinder代码花费相当长的时间!基于Schema的语法强化由XBinder在解码过程中完成。 在XBinder例子中,所有需要添加到基于XBinder的代码中的只是对stat变量的值的一个简单的检查。

XBinder 2.3.1 是当前产品发布版本。此版本发布于2013年12月4日。

此版本增加了 新特性, 包含对Visual Studio 2012; 64-bit Windows 库的支持; 以及在Java和C #中对nillable元素的支持(C和C++中已经支持)。

XBinder 特性现在包括:

  • 包含在每一个授权包中的Java和C#运行库资源。
  • 直接支持在Android平台上使用的Java子集。
  • 在C/C++中生成支持OpenSSL的客户端程序的功能。
  • 解析XSD 1.1语法的能力(虽然目前对于新的XSD 1.1功能暂不提供支持) 。
  • 代码可以生成C,C++,Java和C#四种不同的语言。
  • 跨平台的XML架构编辑和编译GUI,以及一个指导新用户完成代码生成过程的向导界面。
  • 加入自动完成机制,XBinder编辑器GUI(XBEditor)现在使得架构(Schema)组成更容易。可以使用Xerces C++的一个接口进行架构有效性检查。
  • 支持UTF-8, UTF-16和ISO-8859-1 。现在可以以任何一种格式读写文件。
  • 改进对WSDL/SOAP的支持,包括对SOAP 1.2的支持。
  • 支持XML规范化(C14N)格式编码的文件。
  • 现在支持通过使用自由格式文本字段的混合内容。
  • 添加到允许XSD类型到C/C++类型的自定义映射关系的配置选项。
  • 添加到使用C++ STL的字符串类,而不是内置的字符串类的选项。
  • 现在可以添加用来压缩/解压XML文本的zlib紧缩函数调用到生成的reader和writer中。