- 你所在位置:首页 〉VS.net〉XML〉XML经验〉支持 XML Web 服务的 Office 文档 (Extreme XML)
- 支持 XML Web 服务的 Office 文档 (Extreme XML)
- 作者:佚名 文章来源:http://msdn2.microsoft.com/zh-cn/default.aspx 发布日期:2007-07-07 浏览次数:577
-
- 打印这篇文章
-
本页内容
您是否准备就绪,将 Microsoft Office XP 和 .NET Web 服务进行结合?在 B2B 电子商务的网络世界中,为什么不将业务处理工作流集成到人们从其桌面所做的一切事情中,从而向最终用户提供 Web 服务的强大功能?我在谈论什么?哦,我在谈论一个看起来有些象图 1 所示的 Excel 电子表格。
图 1. 支持 Web 服务的 Excel 电子表格
这可不是一个普通的电子表格。它使用 UDDI 来查找公司的地址,并使用目录 Web 服务来查找产品信息。当您单击 Send 按钮时,它还会对 XML 电子表格格式进行 XML 转换,生成一个 RosettaNet PIP 3 A4 采购定单申请格式。
键入要购买其商品的公司名称后,单击 Find 按钮,电子表格下的某个 VBA 代码将调用 UDDI 并填写地址部分其余的内容。例如,键入 Microsoft,单击 Find,您将在 Purchase From 字段中看到下面的内容:
图 2. Purchase From 字段
键入数量(例如 23),并在 description 字段中键入 Pear,然后按 Tab 键,某个 VBA 代码将查询 SOAP 目录 Web 服务,看是否有匹配的产品,并填写详细信息。在本例中,我已将目录 Web 服务连接到 Northwind 数据库,因此它将返回以下信息:
图 3. 电子表格采购定单部分的详细情况
在本例中,还填写了说明并将其转化为一个指向详细介绍此产品的 HTML 页面的链接。
如果找到多个产品但没有一项完全满足您键入的条件,则将提供一个选项下拉列表。例如,如果您键入 tofu,您将看到下列选项:
图 4. 未找到完全匹配项时所提供的多个选项的示例
如果您选择其中一项,则将提供此项的具体详细信息。
完成后,单击 Send 按钮,即生成 RosettaNet PIP 3 A4 XML 采购定单格式,并发送该定单。
通过访问 Tools 菜单,选择 Macro,然后选择 Visual Basic Editor,您可以浏览 VBA 代码。ThisWorkbook 下的某些代码会对电子表格中的变更做出响应,特别是当您删除说明时,Workbook_SheetChange 事件将清除一个行项目;当您将 Description 字段移入 SKU 字段时,Workbook_SheetSelectionChange 事件将调用 FindProduct()。如果 FindProduct 返回 XMLNode,将从该节点提取出相关的字段,以填充行项目的其余详细信息。
有关 UDDI find_business 调用的工作方式,可查阅我以前的一篇文章 UDDI:An XML Web Service。如果找到一家公司,则在 UDDI 响应的 /businessInfo/contacts/contact/address/ 部分中找到的 addressLines 将用来填充 Purchase From 地址块。
Catalogs 模块中的 FindProduct 函数将使用包含搜索项的 URL 参数来调用目录服务 URL。它会得到一个 SOAP 响应并首先检查是否与 /Envelope/Body/Fault 匹配,如果返回的不是 Fault,它将继续打开 〈CatalogQueryResult> 检查,以查看返回项目中的 ProductName 属性是否与给定项相匹配。它还会在可视区域以外的页面创建下拉选项列表。您可以在 Data 菜单中选择 Validation 来查看下拉列表的工作方式。
目录 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=tofu 将返回以下结果:
〈Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
〈Body>
〈CatalogQueryResult xmlns="urn:schemas-b2b-fun:catalogs">
〈item ProductName="Tofu" UnitPrice="23.25"
UnitOfMeasure="40 - 100 g pkgs." SKU="S6-P14"/>
〈item ProductName="Longlife Tofu" UnitPrice="10"
UnitOfMeasure="5 kg pkg." 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>
