分享
 
 
 

Tuxedo 8.1 XML C++ Parser的使用(转自BEA中国网站)

王朝c#·作者佚名  2006-12-17
窄屏简体版  字體: |||超大  

时间:2003-12-05

作者:经乾(dev2dev ID: jq75) BEA系统(中国)有限公司 渠道部技术顾问

在TUXEDO 8.0中,客户机和服务器之间可以使用XML缓冲区进行数据交换,但由于8.0版本没有集成XML Parser,所以对XML的支持是有限的。从8.1版本开始,TUXEDO集成了Apache Xerces C++ Parser 1.7,这样服务器端就可以直接分析XML文档了,而不用再去调用其它XML Parser。

TUXEDO 8.1的samples中给了一个xmlstockapp例子,由于它太复杂(至少我这么认为),因此,本文将通过一个简单实用的例子来介绍XML缓冲区使用。

一.XML缓冲区的分配和传输

XML缓冲区支持的最大长度是4GB,分配方法与CARRAY缓冲区一样,需要指定长度。客户端需要打开一个XML文档,以字符方式读取文档内容,保存到缓冲区中,然后由tpcall()调用提交给服务进程。清单1-1是通信录应用程序的XML客户机代码段。

清单1-1 XML缓冲区客户机代码段,文件名:XML_cli.c

#define XMLDOCSIZE 1048576

... ...

FILE *xml_fd;

char *xml_buffer = NULL;

if ((xml_fd = fopen("friends.xml", "r")) != NULL) {

xml_buffer = (char *)malloc(sizeof(char) * XMLDOCSIZE);

nsize = fread(xml_buffer, sizeof(char), XMLDOCSIZE, xml_fd);

}

sendlen = nsize + 1; /* 实际读取的长度 */

if((sendbuf = (char *) tpalloc((char *)"XML", NULL, sendlen)) == NULL) {

fprintf(stderr,"Error allocating send buffer, tperrno=%ld\n",tperrno);

tpterm();

return(1);

}

strncpy(sendbuf, xml_buffer, nsize);

ret = tpcall((char *)"ADD_FRIEND", (char *)sendbuf, sendlen, (char **)&rcvbuf, &rcvlen, TPNOTIME);

... ...

复制到缓冲区的XML文件必须遵循1.0标准,可以包含任何自定义的标记。本例中用到了friends.xml,这个文件包含了两条要添加到数据库好友信息,内容如清单1-2所示。

清单1-2 XML文件示例,文件名:friends.xml

<?xml version='1.0' encoding='UTF-8'?>

<friends>

<friend>

<friend_id>1</friend_id>

<fname>JQ</fname>

<fmobile>13910793488</fmobile>

</friend>

<friend>

<friend_id>2</friend_id>

<fname>Snna</fname>

<fmobile>13663129935</fmobile>

</friend>

</friends>

二.基于XML标记的DDR

XML缓冲区支持基于标记值的DDR,对于通信录应用程序来说,如果我们要把friend_id取值在1-10范围内的记录保存在table1中,把取值在11-20范围内的记录保存在table2中,把其它取值范围的记录保存在table3中,则可以在ubb配置文件中定义下面的路由标准来实现:

*ROUTING

symbol FIELD="friends/friend/ friend_id"

BUFTYPE="XML"

FIELDTYPE=LONG

RANGES="1-10:GROUP1,11-20:GROUP2,*:GROUP3"

XML缓冲区的路由字段还可以是STRING类型的,这时RANGES的取值必须用单引号引起来,请看如下代码段:

*ROUTING

symbol FIELD="stockquotes/stock_quote/symbol"

BUFTYPE="XML"

FIELDTYPE=STRING

RANGES="'BEAS'-'BEAS':GROUP1, 'MSFT'-'MSFT':GROUP2"

三.XML缓冲区的分析

服务器端收到XML缓冲区后,需要对它进行分析,从中取出标记值。Tuxedo 8.1集成了Apache Xerces C++ Parser 1.7,并提供了两种类型的分析器:SAX Parser和DOM Parser,服务器端通常使用DOM Parser,客户端通常使用SAX Parser。使用Xerces C++ Parser的步骤一般是:

· 初始化XMLC42系统;

XMLPlatformUtils::Initialize();

· 根据XML缓冲区创建MemBufferInputSource;

MemBufInputSource* memBufIS =

new MemBufInputSource( (const XMLByte*)xmlbuf, strlen(xmlbuf), bufId, false);

· 创建SAX Parser或DOM Parser;

DOMParser *parser = new DOMParser;

SAXPArser *parser = new SAXParser;

· 对于SAX Parser,需要为文档和错误处理设置回调函数;

SAXPrintHandlers handler;

parser->setDocumentHandler(&handler);

parser->setErrorHandler(&handler);

· 调用Xerces C++ Parser分析XML缓冲区;

parse->parse(*memBufIS);

· 删除Parser和MemBufferInputSource;

delete parser;

delete memBufIS;

· 退出XMLC42系统;

XMLPlatformUtils::Terminate();

对于通信录应用程序来说,客户机给服务器传递了friends.xml文件,服务器端创建了一个DOM Parser对它进行分析,并把结果存入数据库,代码如清单1-3所示。

清单1-3 XML缓冲区的服务器代码,文件名:XML_serv.pc

#include <xercesc/parsers/DOMParser.hpp>

#include <xercesc/util/PlatformUtils.hpp>

#include <xercesc/framework/MemBufInputSource.hpp>

#include <atmi.h>

#include <userlog.h>

#include <stdlib.h>

#include <string.h>

char *localbuf=NULL;

static const char* bufId = "mybuf";

EXEC SQL begin declare section;

static long friend_id;

static char fname[10];

static char fmobile[14];

EXEC SQL end declare section;

EXEC SQL INCLUDE sqlca;

void TopTree( DOM_Node node);

void SubTree( DOM_Node node);

void parseXMLBuffer(char** xmlbuf);

#ifdef __cplusplus

extern "C"

#endif

void

#if defined(__STDC__) || defined(__cplusplus)

ADD_FRIEND(TPSVCINFO *rqst)

#else

ADD_FRIEND(rqst)

TPSVCINFO *rqst;

#endif

{

parseXMLBuffer(&rqstàdata);

tpreturn(TPSUCCESS, 0, xmlbuf, rqstàlen, 0);

}

void parseXMLBuffer(char** xmlbuf)

{

int errorCount ;

localbuf = (char *)malloc(sizeof(char *) * 2048);

XMLPlatformUtils::Initialize();

MemBufInputSource* memBufIS =

new MemBufInputSource( (const XMLByte*)*xmlbuf, strlen(*xmlbuf)-1, bufId, true);

DOMParser *parser = new DOMParser;

parseràparse(*memBufIS);

if ((errorCount = parseràgetErrorCount()) == 0)

{

DOM_Document document = parseràgetDocument();

DOM_Element topLevel = document.getDocumentElement();

TopTree(topLevel);

}

delete parser;

delete memBufIS;

XMLPlatformUtils::Terminate();

}

void TopTree( DOM_Node node){

if (node.getNodeType() == DOM_Node::ELEMENT_NODE)

{

if (node.getNodeName().equals ("friend")) SubTree(node);

else

{

DOM_NodeList children = node.getChildNodes();

for (int i=0; i<children.getLength(); i++) TopTree(children.item(i));

}

}

}

void SubTree( DOM_Node node){

DOM_NodeList children = node.getChildNodes();

for (int i=0; i<children.getLength(); i++)

{

DOM_Node nod = children.item(i);

if(nod.getNodeType()==DOM_Node::ELEMENT_NODE)

{

if(nod.getNodeName().equals("friend_id"))

friend_id = atol(nod.getFirstChild().getNodeValue().transcode());

else if(nod.getNodeName().equals("fname"))

strcpy(fname, nod.getFirstChild().getNodeValue().transcode());

else if(nod.getNodeName().equals("fmobile"))

strcpy(fmobile, nod.getFirstChild().getNodeValue().transcode());

}

}

EXEC SQL insert into FRIEND (FRIEND_ID,NAME,MOBILE)

values (:friend_id, :fname, :fmobile);

if (SQLCODE != SQL_OK) userlog("Cannot insert into FRIEND");

}

注意:服务器文件名为XML_serv.pc,先要使用esqlc命令对它作预编译,生成C源程序,然后把扩展名改为cpp,才能用buildserver来编译,原因是Xerces C++ Parser只提供了C++的编程接口。读者可以参考如下命令来编译:

proc iname=XML_serv.pc oname=XML_serv.cpp

buildserver -v -s ADD_FRIEND -f XML_serv.cpp -o XML_serv -f %TUXDIR%\lib\libtxml.lib

四.UBBConfigNT配置文件的编写

这个例子使用了Oracle8i数据库来测试,Tuxedo的配置文件如清单1-4所示。

清单1-4 Tuxedo的配置文件,文件名:UBBConfigNT

*RESOURCES

IPCKEY 123456

DOMAINID simpapp

MASTER SITE1

MAXACCESSERS 10

MAXSERVERS 5

MAXSERVICES 10

MODEL SHM

LDBAL N

*MACHINES

DEFAULT:

APPDIR="C:\TuxDAP\solutions\xml"

TUXCONFIG="C:\TuxDAP\solutions\xml\tuxconfig"

TUXDIR="G:\bea\tuxedo"

TLOGNAME=TLOG

TLOGDEVICE="C:\TuxDAP\solutions\xml\TLOG"

JQ LMID=SITE1

*GROUPS

DEFAULT: LMID=SITE1

GROUP1 LMID=simple GRPNO=1

OPENINFO="Oracle_XA:Oracle_XA+Acc=P/scott/tiger+SqlNet=oradb+SesTm=120+

MaxCur=5+LogDir=."

TMSNAME="TMS_ORA8i" TMSCOUNT=2

*SERVERS

DEFAULT: RESTART=Y MAXGEN=5 REPLYQ=Y CLOPT="-A"

XML_serv SRVGRP=GROUP1 SRVID=10

*SERVICES

ADD_FRIEND

*ROUTING

五.运行测试

执行XML_Cli.exe进行测试,friends.xml文件已经通过XML缓冲区成功地发送到服务器端;

打开SQL*PLUS,查看一下FRIEND表的内容,发现里面已经插入了两条记录,这两条记录的数据就是通过friends.xml文件来传输的!

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有