本文将给出现实生活中如何在一个BEA
tuxedo 8.1应用程序中使用XML的例子。假如您持有一个定位于通过交换XML数据来集成某些应用程序的项目,那么对于了解“我如何实现这一点”,本文将是一个很好的介绍。
本文的对象是那些已经对Tuxedo有所了解,但从未使用过Tuxedo内嵌的XML缓冲功能的架构师和开发人员。
Tuxedo中XML的历史
如今随着XML逐渐成为主流的数据格式之一,自然而然地Tuxedo将之作为一种基本缓冲类型予以支持。 Tuxedo 7.1 引入了XML缓冲类型,但迄今为止对于Tuxedo中的XML并无较多的论述。Tuxedo 7.1中并未携带真正的XML API,因为通常认为将开发人员自己最喜欢的DOM或SAX实现合并到其应用程序中是其自身的责任。
现在,由于在Tuxedo内嵌了Xerces 1.7 版本(来自Apache XML项目)库,所以伴随Tuxedo 8.1提供了一套真正的XML API。8.1版本还包含了一个称为xmlstockapp(xml股票程序)的XML示例。
这一点为开发人员增加了许多XML功能,例如XML解析,XML树遍历或构建,以及XML格式化,从而不需要使用外部的产品。
何为XML?
XML经常作为一种“语言”被提及,然而它实际上是一种用于描述文本缓冲区中的层次结构数据集的标准格式。这种数据格式可以通过一种加强数据结构和层次关系的本地语法(称为DTD)来进行控制。
我如何在XML中进行编码?
XML并非一种语言,而是一种数据格式。编码意味着使用一种API,从一个纯文本缓冲区到数据树来回进行数据转换,或者对数据树进行遍历或操��。想要了解如何使用XML进行编码,请参看下文“……一般任务”一节。
有哪些可用的API对XML进行操纵作?
目前存在数种标准API对XML进行操纵,最著名的是DOM,SAX和XPATH。所有的API都针对不同语言具有不同的实现,但是本文仅仅关注Tuxedo 8.1产品中包含的Xerces的C/C++实现。
我应在何时使用XML?
由于XML是一种标准的有组织的格式,如今它已经成为一种广为使用的便利格式来在不同系统间进行数据交换。即使结构上(DTD)略作改动来添加一些子节点或新属性,XML的自描述性和结构化的方式也有助于数据的理解。XML也是易于阅读的,而二进制数据则不然。
然而XML仍具有一些缺点:
它使您���数据大幅膨胀(每个域将增加一个20字节左右的标题,并且所有的二进制域将扩大为相应的字符串表达)。
在进行解析和格式化时它增加了CPU的开销,尤其是在解析和检验文档是否是“格式良好”时。
其API均比较复杂。
因此XML是一种理想的集成语言,但是在系统内部您可能并非处处都需要使用它。在Tuxedo中它通常用于同外部系统发送和接收数据。
对于使用DOM API处理XML数据的程序的一般任务:
这些任务并非只针对Tuxedo,而是适用于所有使用DOM处理XML数据的程序。
初始化Xerces
一旦您希望使用Xerces API进行工作就必须强制进行初始化:
try
{
XMLPlatformUtils::Initialize ();
}
catch (const XMLException & toCatch)
{
char *pMsg = XMLString::transcode (toCatch.getMessage ());
userlog ("Error during Xerces-c Initialization.\n"
" Exception message: %s", pMsg);
delete[]pMsg;
return -1;
}
解析XML文本
当XML 数据被接收时,它通常是一个文本缓冲区或一个文件。DOM API是一种用于处理数据节点树的API,这种节点树通常由包含了属性和其他元素的元素构成。一个程序可以通过递归扫描元素节点来遍历DOM树。
如果一个程序希望通过层次结构,元素名称或者属性来访问缓冲区内的数据,该缓冲区首先需要被读入并转化为一棵数据树。这一过程被称为解析。要执行文本解析您需要实现一个来源类(LocalFileInputSource或MemBufInputSource)来容纳将要解析的文本,并使用DOMParser的实现来进行解析。
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/framework/XMLFormatter.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>
#include <xercesc/parsers/DOMParser.hpp>
#include <xercesc/dom/DOM_Node.hpp>
char *xmlFileName = "./myfile.xml";
DOMParser *parser = 0;
DOM_Document document;
DOM_Element topLevel;
LocalFileInputSource source (XMLString::transcode (xmlFileName));
//
// Create our parser, then set the parsing options.
// discovers errors during the course of parsing the XML document.
//
parser = new DOMParser ();
parser->setValidationScheme (DOMParser::Val_Never);
parser->setDoNamespaces (false);
parser->setDoSchema (false);
parser->setValidationSchemaFullChecking (false);
parser->setCreateEntityReferenceNodes (false);
parser->setToCreateXMLDeclTypeNode (true);
//
// Parse the XML file, catching any XML exceptions that might propagate
// out of it.
//
try {
parser->parse (source);
int errorCount = parser->getErrorCount ();
if (errorCount > 0) {
printf("%d error(s) occured during parsing config\n", errorCount);
goto clean;
}
}
catch (const XMLException & e) {
printf("An error occured during parsing \n Message: %s\n"
"", e.getMessage ());
goto clean;
}
catch (const DOM_DOMException & e) {
printf("A DOM error occured during parsing config\n"
"Exception code: %d\n", e.code);
goto clean;
}
catch (...) {
printf ("An error occured during parsing config\n");
goto clean;
}
…