監(jiān)理公司管理系統(tǒng) | 工程企業(yè)管理系統(tǒng) | OA系統(tǒng) | ERP系統(tǒng) | 造價咨詢管理系統(tǒng) | 工程設(shè)計管理系統(tǒng) | 甲方項目管理系統(tǒng) | 簽約案例 | 客戶案例 | 在線試用
X 關(guān)閉

MSDN Online Voices - Extreme XML:已啟用XML Web服務(wù)的Office文檔

申請免費試用、咨詢電話:400-8352-114

AMTeam.org

MSDN Online Voices - Extreme XML:已啟用XML Web服務(wù)的Office文檔

 

Microsoft Office XP 和 .NET Web 服務(wù)已經(jīng)聯(lián)姻,您準備好了嗎?在 B2B 電子商務(wù)網(wǎng)絡(luò)世界中,為什么不將業(yè)務(wù)處理流程同人們在計算上所做的一切結(jié)合起來,從而將 Web 服務(wù)的強大動力傳遞到最終用戶?我在談?wù)撌裁矗颗?,我在談?wù)撘粋€看起來有些象圖 1 所示的 Excel 電子表格。

 
圖 1:已啟用 Web 服務(wù)的 Excel 電子表格

這可不是一份普通的電子表格。它使用 UDDI 來查找公司的地址,并使用目錄 Web 服務(wù)來查找產(chǎn)品信息。當您單擊“發(fā)送”按鈕后,它還會對 XML 電子表格格式進行 XML 轉(zhuǎn)換,生成一個 RosettaNet(英文)PIP 3 A4 訂單申請格式。

鍵入要購買其商品的公司名稱后,單擊“查找”按鈕,電子表格下的某個 VBA 代碼將調(diào)用 UDDI 并完成地址部分其余的內(nèi)容。例如,鍵入 Microsoft,單擊“查找”,您將在“賣方”域中看到下面的內(nèi)容:

 
圖 2:“賣方”域

鍵入數(shù)量,例如 23,并在說明域中鍵入 Pear,然后按 Tab,某個 VBA 代碼將查詢 SOAP 目錄 Web 服務(wù),以查看是否有匹配的產(chǎn)品,并列出詳細信息。在本例中,我已將目錄 Web 服務(wù)連接到 Northwind 數(shù)據(jù)庫,因此它將返回以下信息:

 
圖 3:電子表格訂購部分的詳細情況

在本例中,還列出了說明并將其轉(zhuǎn)換為一個連接到詳細介紹此產(chǎn)品的 HTML 頁面的鏈接。

如果找到多個產(chǎn)品但沒有一項完全滿足您鍵入的條件,則將提供一個選項下拉列表。例如,如果鍵入豆腐,您將看到下列選項:

 
圖 4:未找到完全匹配項時所提供的多個選項的示例

如果您選擇其中一項,則將提供此項的詳細信息。

完成后,單擊“發(fā)送”按鈕,即生成 RosettaNet PIP 3 A4 XML 訂單格式,訂單也同時發(fā)出。

如何實現(xiàn)?

通過訪問“工具”菜單,選擇“宏”,然后選擇“Visual Basic 編輯器”,您可以瀏覽 VBA 代碼。ThisWorkbook 下的某些代碼會對電子表格中的變更做出響應(yīng),特別是當您刪除說明時,Workbook_SheetChange 事件將清除一個項目行;當您將“說明”域移入“SKU”域時,Workbook_SheetSelectionChange 事件將調(diào)用 FindProduct()。如果 FindProduct 返回 XMLNode,將從該節(jié)點拉出相關(guān)的域,以填充項目行的其他詳細信息。

有關(guān) UDDI find_business 調(diào)用的工作方式,您可以查閱我的另一篇文章 UDDI:一種 XML Web 服務(wù)。如果找到一項業(yè)務(wù),在 UDDI 響應(yīng)的 /businessInfo/contacts/contact/address/ 部分找到的 addressLines 將被用來填充“賣方”地址塊。

目錄 Web 服務(wù)

Catalogs 模塊中的 FindProduct 函數(shù)將使用包含搜索項的 URL 參數(shù)來調(diào)用目錄服務(wù) URL。它會得到一個 SOAP 響應(yīng)并首先檢查是否與 /Envelope/Body/Fault 匹配,如果返回的不是 Fault,它將繼續(xù)打開 <CatalogQueryResult>,以檢查返回項目中的 ProductName 屬性是否與給定的范圍相匹配。它還會在可視區(qū)域以外的頁面創(chuàng)建下拉選項列表。您可以在“數(shù)據(jù)”菜單中選擇“驗證”來查看下拉列表的工作方式。

目錄 Web 服務(wù)十分簡單。.aspx 入口點將創(chuàng)建一個 CatalogSearch 對象,該對象在 search.cs 中定義,并調(diào)用 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 寫入以下內(nèi)容的 while 循環(huán):

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=豆腐將返回以下結(jié)果:

<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。

“發(fā)送”按鈕

SendOrder() 函數(shù)可按電子表格中選定范圍的單元格的 XML 表示形式加載 XML 文檔。通過下列神奇的 VBA 代碼行便可以實現(xiàn)這一切:

With ActiveSheet

Set sourcexml = New MSXML2.DOMDocument
 
sourcexml.loadXML .Range("B1:N34").value(xlRangeValueXMLSpreadsheet)
End With

這將返回一個巨大的 XML 程序塊,完整說明有關(guān)電子表格中選定范圍的單元格的全部信息。以下是 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 將它轉(zhuǎn)換為以下格式:

<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 訂單申請規(guī)范,這可能不是一份技術(shù)上完整的申請,但您可以由此得到啟發(fā)。

提高此轉(zhuǎn)換的強壯性的技巧在于命名要從中導(dǎo)出數(shù)據(jù)的重要單元格。這可以通過 XSLT 轉(zhuǎn)換中下列樣式的 XPath 表達式來實現(xiàn):

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

此特定表達式將查找名稱為 City 的單元格。而樣式表的其余部分將被忽略。有關(guān)詳細信息,請參閱 XLToPO.xsl。

嘗試使用

要運行此函數(shù),您只需安裝 MSXML 3.0 并獲取一份 Northwind 數(shù)據(jù)庫。演示代碼將按以下方式連接至 SQL Server:

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

如果 Northwind 數(shù)據(jù)庫位于其他位置,您需要更改此代碼位。

PO.xsl 電子表格假定目錄服務(wù)位于:

http://localhost/catalog/search.aspx

您需要在本地計算機的名為 catalog 的虛擬目錄中安裝 Web 服務(wù) search.aspx、search.cs 和 XLToPO.xsl,或者將電子表格指向別處。

要編輯電子表格,您必須關(guān)閉保護(可以使用“工具/保護”子菜單關(guān)閉)。

下一步

您可能希望將供應(yīng)商的目錄服務(wù)綁定保存到 UDDI 中。有一些 VBA 代碼能幫您做到這一點。該代碼將查找可識別的目錄服務(wù) serviceInfo(通過 serviceKey),如果找到,代碼將使用包含在 serviceDetails 中的 accessPoint。我在本演示中所使用的偽目錄 API 并沒有作為 UDDI 中的已知服務(wù)類型進行注冊。

使用 Office Smart Tag 來做類似的工作可能會是一種比較有趣的體驗。有關(guān)詳細信息,請參閱 http://msdn.microsoft.com/office/(英文)上的 Smart Tag SDK。

發(fā)布:2007-03-25 13:22    編輯:泛普軟件 · xiaona    [打印此頁]    [關(guān)閉]
相關(guān)文章:
石家莊OA系統(tǒng)
聯(lián)系方式

成都公司:成都市成華區(qū)建設(shè)南路160號1層9號

重慶公司:重慶市江北區(qū)紅旗河溝華創(chuàng)商務(wù)大廈18樓

咨詢:400-8352-114

加微信,免費獲取試用系統(tǒng)

QQ在線咨詢