分享
 
 
 

Microsoft Office XP 和 .NET Web 服务的应用---启用 XML 服务的 Office 文档(*****)

王朝vb·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

已启用 XML Web 服务的 Office 文档

下载此专栏的样例代码

Microsoft Office XP 和 .NET Web 服务已经联姻,您准备好了吗?在 B2B 电子商务网络世界中,为什么不将业务处理流程同人们在计算上所做的一切结合起来,从而将 Web 服务的强大动力传递到最终用户?我在谈论什么?哦,我在谈论一个看起来有些象图 1 所示的 Excel 电子表格。

图 1:已启用 Web 服务的 Excel 电子表格

这可不是一份普通的电子表格。它使用 UDDI 来查找公司的地址,并使用目录 Web 服务来查找产品信息。当您单击“发送”按钮后,它还会对 XML 电子表格格式进行 XML 转换,生成一个 RosettaNet(英文)PIP 3 A4 订单申请格式。

键入要购买其商品的公司名称后,单击“查找”按钮,电子表格下的某个 VBA 代码将调用 UDDI 并完成地址部分其余的内容。例如,键入 Microsoft,单击“查找”,您将在“卖方”域中看到下面的内容:

图 2:“卖方”域

键入数量,例如 23,并在说明域中键入 Pear,然后按 Tab,某个 VBA 代码将查询 SOAP 目录 Web 服务,以查看是否有匹配的产品,并列出详细信息。在本例中,我已将目录 Web 服务连接到 Northwind 数据库,因此它将返回以下信息:

图 3:电子表格订购部分的详细情况

在本例中,还列出了说明并将其转换为一个连接到详细介绍此产品的 HTML 页面的链接。

如果找到多个产品但没有一项完全满足您键入的条件,则将提供一个选项下拉列表。例如,如果键入豆腐,您将看到下列选项:

图 4:未找到完全匹配项时所提供的多个选项的示例

如果您选择其中一项,则将提供此项的详细信息。

完成后,单击“发送”按钮,即生成 RosettaNet PIP 3 A4 XML 订单格式,订单也同时发出。

如何实现?

通过访问“工具”菜单,选择“宏”,然后选择“Visual Basic 编辑器”,您可以浏览 VBA 代码。ThisWorkbook 下的某些代码会对电子表格中的变更做出响应,特别是当您删除说明时,Workbook_SheetChange 事件将清除一个项目行;当您将“说明”域移入“SKU”域时,Workbook_SheetSelectionChange 事件将调用 FindProduct()。如果 FindProduct 返回 XMLNode,将从该节点拉出相关的域,以填充项目行的其他详细信息。

有关 UDDI find_business 调用的工作方式,您可以查阅我的另一篇文章 UDDI:一种 XML Web 服务。如果找到一项业务,在 UDDI 响应的 /businessInfo/contacts/contact/address/ 部分找到的 addressLines 将被用来填充“卖方”地址块。

目录 Web 服务

Catalogs 模块中的 FindProduct 函数将使用包含搜索项的 URL 参数来调用目录服务 URL。它会得到一个 SOAP 响应并首先检查是否与 /Envelope/Body/Fault 匹配,如果返回的不是 Fault,它将继续打开 <CatalogQueryResult>,以检查返回项目中的 ProductName 属性是否与给定的范围相匹配。它还会在可视区域以外的页面创建下拉选项列表。您可以在“数据”菜单中选择“验证”来查看下拉列表的工作方式。

目录 Web 服务十分简单。.aspx 入口点将创建一个 CatalogSearch 对象,该对象在 search.cs 中定义,并调用 Execute 按下列方式传递 HttpResponse 输出流:

<%@Language="C#" src="search.cs" Debug="true" %>

<%

Response.ContentType = "text/xml";

string term = Request.QueryString["term"];

if (term != null) {

CatalogSearch s = new CatalogSearch(term);

s.Execute(output);

} else {

Response.Write("<Empty/>");

}

%>

真正的乐趣将从 Execute 方法开始。它是一个捆绑在 XmlTextWriter 中的、十分简单的 SQL 托管提供程序代码,能够从 SQL SELECT 语句返回特定的域。因此,它基本上是一个通过 DataReader 向 XmlTextWriter 写入以下内容的 while 循环:

public void Execute(TextWriter stm)

{

XmlTextWriter xw = new XmlTextWriter(stm);

xw.WriteStartElement("Envelope", "http://schemas..../envelope/");

xw.WriteStartElement("Body", "http://schemas..../envelope/");

try {

String const = "server=localhost;uid=sa;pwd=;database=northwind";

SQLConnection con = new SQLConnection(constr);

con.Open();

IDataReader reader;

String query = "SELECT ProductName,UnitPrice,QuantityPerUnit," +

"SupplierID,ProductID FROM Products WHERE " +

"ProductName LIKE '%" + term + "%'";

SQLCommand cmd = new SQLCommand(query, con);

cmd.Execute(out reader);

string funNamespace = "urn:schemas-b2b-fun:catalogs";

xw.WriteStartElement("CatalogQueryResult", funNamespace);

while (reader.Read())

{

xw.WriteStartElement("item");

xw.WriteAttribute("ProductName", reader.GetString(0));

xw.WriteAttrDecimal("UnitPrice", reader.GetDecimal(1));

xw.WriteAttribute("UnitOfMeasure", reader.GetString(2));

xw.WriteAttribute("SKU", "S"+reader.GetInt32(3)+

"-P"+reader.GetInt32(4));

xw.WriteEndElement();

}

xw.WriteEndElement();

con.Close();

} catch (Exception e) {

xw.WriteStartElement("Fault");

xw.WriteElementString("faultcode","500");

xw.WriteElementString("faultstring",e.ToString());

xw.WriteEndElement();

}

xw.WriteEndElement();

xw.WriteEndElement();

xw.Close();

}

URL http://localhost/catalog/search.aspx?term=豆腐将返回以下结果:

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">

<Body>

<CatalogQueryResult xmlns="urn:schemas-b2b-fun:catalogs">

<item ProductName="豆腐" UnitPrice="23.25"

UnitOfMeasure="每包装 40 - 100 克" SKU="S6-P14"/>

<item ProductName="长保鲜期豆腐" UnitPrice="10"

UnitOfMeasure="每包装 5 千克" SKU="S4-P74"/>

</CatalogQueryResult>

</Body>

</Envelope>

这可能是使用 .NET 框架从 SQL Server 获得 XML 的最有效的方式。粗略计算,在我的 Dell PowerEdge 2400 上每秒可获得其中的 80 到 90 个这样的 XML。

“发送”按钮

SendOrder() 函数可按电子表格中选定范围的单元格的 XML 表示形式加载 XML 文档。通过下列神奇的 VBA 代码行便可以实现这一切:

With ActiveSheet

Set sourcexml = New MSXML2.DOMDocument

sourcexml.loadXML .Range("B1:N34").value(xlRangeValueXMLSpreadsheet)

End With

这将返回一个巨大的 XML 程序块,完整说明有关电子表格中选定范围的单元格的全部信息。以下是 XML 程序块的代码片断:

<Workbook>

<Worksheet>

<Table>

<Row>

<Cell ss:StyleID="s23"><Data ss:Type="Number">23</Data>

<NamedCell ss:Name="Item"/></Cell>

<Cell ss:MergeAcross="4" ss:StyleID="m31209522"

ss:HRef="http://eshop.msn.com/category.asp?catId=170">

<Data ss:Type="String">鲍勃叔叔的有机干梨

</Data></Cell>

<Cell ss:StyleID="s52">

<Data ss:Type="String">S3-P7</Data></Cell>

<Cell ss:StyleID="s26">

<Data ss:Type="Number">30</Data>

<NamedCell ss:Name="UnitPrice"/></Cell>

<Cell ss:StyleID="s27">

<Data ss:Type="String">每包装 1 磅(12 个)</Data></Cell>

<Cell ss:StyleID="s37">

<Data ss:Type="Number">690</Data></Cell>

<Cell ss:StyleID="s49"/>

</Row>

</Table>

</Worksheet>

</Workbook>

我们可以使用 XSL 将它转换为以下格式:

<PurchaseOrder xmlns="http://www.rosettanet.org">

<deliverTo>

<PhysicalAddress>

<cityName>Seattle, WA, USA 98111</cityName>

<addressLine1>Airport Chocolates</addressLine1>

<addressLine2>2711 Alaskan Way</addressLine2>

<regionName>USA</regionName>

</PhysicalAddress>

</deliverTo>

<ProductLineItem>

<ProductQuantity>23</ProductQuantity>

<productUnit>

<ProductPackageDescription>

<ProductIdentification>

<GlobalProductIdentifier>S3-P7</GlobalProductIdentifier>

</ProductIdentification>

</ProductPackageDescription>

</productUnit>

<Description>鲍勃叔叔的有机干梨</Description>

<requestedPrice>

<FinancialAmount>

<GlobalCurrencyCode>USD</GlobalCurrencyCode>

<MonetaryAmount>30</MonetaryAmount>

</FinancialAmount>

</requestedPrice>

</ProductLineItem>

<thisDocumentGenerationDateTime>

<DateTimeStamp>2001-03-15T00:00:00.000</DateTimeStamp>

</thisDocumentGenerationDateTime>

</PurchaseOrder>

注意:按照 RosettaNet PIP 3 A4 订单申请规范,这可能不是一份技术上完整的申请,但您可以由此得到启发。

提高此转换的强壮性的技巧在于命名要从中导出数据的重要单元格。这可以通过 XSLT 转换中下列样式的 XPath 表达式来实现:

select="/Workbook/Worksheet/Table/Row/Cell[NamedCell[@ss:Name='City']]

此特定表达式将查找名称为 City 的单元格。而样式表的其余部分将被忽略。有关详细信息,请参阅 XLToPO.xsl。

尝试使用

要运行此函数,您只需安装 MSXML 3.0 并获取一份 Northwind 数据库。演示代码将按以下方式连接至 SQL Server:

SQLConnection("server=localhost;uid=sa;pwd=;database=northwind");

如果 Northwind 数据库位于其他位置,您需要更改此代码位。

PO.xsl 电子表格假定目录服务位于:

http://localhost/catalog/search.aspx

您需要在本地计算机的名为 catalog 的虚拟目录中安装 Web 服务 search.aspx、search.cs 和 XLToPO.xsl,或者将电子表格指向别处。

要编辑电子表格,您必须关闭保护(可以使用“工具/保护”子菜单关闭)。

下一步

您可能希望将供应商的目录服务绑定保存到 UDDI 中。有一些 VBA 代码能帮您做到这一点。该代码将查找可识别的目录服务 serviceInfo(通过 serviceKey),如果找到,代码将使用包含在 serviceDetails 中的 accessPoint。我在本演示中所使用的伪目录 API 并没有作为 UDDI 中的已知服务类型进行注册。

使用 Office Smart Tag 来做类似的工作可能会是一种比较有趣的体验。有关详细信息,请参阅 http://msdn.microsoft.com/office/(英文)上的 Smart Tag SDK。

Chris Lovett 是 Microsoft 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- 王朝網路 版權所有