小丽愁眉苦脸的,这样一来,她就没有办法照镜子,这样不会发现她的YSL口红是不是淡了,最近刚买的84号的,正想美丽一下。
小张看到小丽又开始愁眉苦脸,于是想着给她做个中间层,让其它部门通过客户端上报数据,这样是不是更讨小丽的欢心了。
小张说干就干,开始新一轮攻略小丽之路。
XML“可扩展的标记名语言”。XML就是字符串,一种特殊规范的字符串。正因为它是字符串,天生的就具备了广泛的适应性,这也就是我们说用 XML开发中间层SO Easy.
无论哪种语言做中间层, 一般都是选JSON和XML来做数据格式。
VFP关于XML的三个函数
CursorToXML(nWorkArea | cTableAlias, cOutput [, nOutputFormat [, nFlags [, nRecords [, cSchemaName [, cSchemaLocation [, cNameSpace ]]]]]])
XMLTOCURSOR(XMLSource eExpression | cXMLFile [, cCursorName [, nFlags ]])
XMLUPDATEGRAM( [cAliasList [, nFlags]])
CursorToXML(nWorkArea | cTableAlias, cOutput [, nOutputFormat [, nFlags [, nRecords [, cSchemaName [, cSchemaLocation [, cNameSpace ]]]]]])
nWorkArea | cTableAlias--指定被转换光标
cOutput--指定输出文件名称或变量名
nOutputFormat--指定XML文档中数据的格式
这里有三种选择:
A.nOutputFormat=1:ELEMENTS
我们来看一段XML,XML跟HTML很像,也是标签与标签包起来内容 ,以下就是一段树形结构来表示数据
<根>
<树干>
<树叶>
</树叶>
<树干/>
</根>
<employees>
<employeeid>1</employeeid>
<lastname>Davolio</lastname>
<firstname>Nancy</firstname>
<title>Sales Representative</title>
<titleofcourtesy>Ms.</titleofcourtesy>
<birthdate>1948-12-08T00:00:00</birthdate>
<hiredate>1992-05-01T00:00:00</hiredate>
<address>507 - 20th Ave. E. Apt. 2A</address>
<city>Seattle</city>
<region>WA</region>
<postalcode>98122</postalcode>
<country>USA</country>
<homephone>(206) 555-9857</homephone>
<extension>5467</extension>
<notes />
<reportsto>2</reportsto>
<photopath>http://accweb/emmployees/davolio.bmp</photopath>
</employees>
B.nOutputFormat=2:ATTRIBUTES
<employees employeeid="1" lastname="Davolio" firstname="Nancy" title="Sales Representative" titleofcourtesy="Ms." birthdate="1948-12-08T00:00:00" hiredate="1992-05-01T00:00:00" address="507 - 20th Ave. E. Apt. 2A" city="Seattle" region="WA" postalcode="98122" country="USA" homephone="(206) 555-9857" extension="5467" notes="" reportsto="2" photopath="http://accweb/emmployees/davolio.bmp" />
C.nOutputFormat=3:ROW
<row employeeid="1" lastname="Davolio" firstname="Nancy" title="Sales Representative" titleofcourtesy="Ms." birthdate="1948-12-08T00:00:00" hiredate="1992-05-01T00:00:00" address="507 - 20th Ave. E. Apt. 2A" city="Seattle" region="WA" postalcode="98122" country="USA" homephone="(206) 555-9857" extension="5467" notes="" reportsto="2" photopath="http://accweb/emmployees/davolio.bmp" />
nFlags--指定标记
这个参数最为复杂,这里要提请大家注意的是:如果想将XML输出到文件中,请让 nFlags=512+n(n为其他标记);如果想将XML输出到内存变量,nFlags就不用为512;
nRecords--输出的记录范围
一般我们会输出Cursor 中所有的记录,所以这个参数多用0代入!
举例:
输出实例数据库的Employee的数据到C:Temp1.xml中:
CURSORTOXML("employees","c:\temp1.xml",1,512+16,0,"1")
输出实例数据库的Employee的数据到内存变量ABC中:
CURSORTOXML("employees","ABC",3,512+16,0,"1")
XMLTOCURSOR(XMLSource eExpression | cXMLFile [, cCursorName [, nFlags ]])
XMLSource eExpression | cXMLFile--指定XML的来源,可以是文件也可以是内存变量
cCursorName --新的Cursor的名称
举例:
将c:\temp1.xml 转变成为cursor:T1
XMLToCursor("c:\temp1.xml","T1")
将内存变量转变成为cursor:T2
XMLToCursor("c:\temp2.xml","T2")
有了这两个函数,搞定一般的中间层没有什么问题。
dataset 就是.NET 的dataset 对象,他生成的XML是可以有多个表信息的。
DataSet是.NET的一种XML格式,VFP可以轻易转换成表。
这里先提一下,下一篇再细细讲解一下这个类。
cXML=.net DATASET转换的XML
loXMLAdapter = CREATEOBJECT("XMLAdapter")
loXMLAdapter.LoadXML(cXML)
*--可以设置字段类型的
loXMLAdapter.Tables(1).Fields(2).DataType = "C"
loXMLAdapter.Tables(1).Fields(2).MaxLength = 30
lcAlias = loXMLAdapter.Tables.Item(1).Alias
loXMLAdapter.Tables.Item(1).ToCursor()
说明:将缓冲表或临时表中的更改反映到 XML UpdateGram 中,并返回包含 UpdateGram 的字符串。
XMLUPDATEGRAM( [ cAliasList [, nFlags [, cSchemaLocation]]])
这个函数需要配合缓冲表来使用,VFP的缓冲表可以记录表的新增,修改,删除三种状态,那我们就可以把这三种状态转换成对应的XML格式。
我们对教师表进行新增,修改,删除,然后执行XMLUPDATEGRAM("教师")
before 为修改之前的数据,after为修改之后的数据
<updg:before>
<教师>
<id>5</id>
<老师编号>001</老师编号>
<老师姓名>张三</老师姓名>
</教师>
</updg:before>
<updg:after>
<教师>
<id>5</id>
<老师编号>001</老师编号>
<老师姓名>56565</老师姓名>
</教师>
</updg:after>
<updg:after>
<教师>
<id>13</id>
<老师编号>5555</老师编号>
<老师姓名>新增</老师姓名>
<物理地址/>
<ip/>
<日期/>
</教师>
</updg:after>
<updg:before>
<教师>
<id>12</id>
<老师编号/>
<老师姓名>io</老师姓名>
</教师>
</updg:before>
<updg:after/>
VFP前端表单把缓冲表生成这样的XML,然后发送给VFP中间层XML。
中间层处理这些XML完成之后,如保存成功,就可以给前端发送保存成功的XML,这样前端就可以TABLEUPDATE进行临时表保存,处理掉缓冲的各项修改。如保存失败,将失败原因发送给VFP前端。
关于把缓冲变化更新的两种模式,一种通用(可以定制自己的传递标准),一种VFP约定专用的格式。