XML Web Service-Enabled Office Dokumente
Chris Lovett
Microsoft Corporation
19. März 2001
Laden Sie Xml03192001.exeherunter .
Sind Sie bereit für eine Ehe von Microsoft Office XP und .NET-Webdiensten? In einer netzwerkierten Welt von B2B-E-Commerce liefern Sie nicht die Leistungsfähigkeit von Webdiensten an den Endbenutzer, indem Sie den Geschäftsprozessworkflow direkt in alle Personen integrieren, die von ihrem Desktop aus tun? Was spricht ich über? Nun, eine Excel Kalkulationstabelle, die wie Abbildung 1 aussieht.
.gif)
Abbildung 1. Kalkulationstabelle Excel für Webdienste
Dies ist nicht nur eine normale Kalkulationstabelle. Sie verwendet UDDI, um Unternehmensadressen zu finden und verwendet einen Katalogwebdienst, um Produktinformationen zu finden. Außerdem wird eine XML-Transformation im XML-Tabellenkalkulationsformat ausgeführt, um ein RosettaNet PIP 3 A4-Bestellanforderungsformat zu generieren, wenn Sie auf die Schaltfläche " Senden " klicken.
Wenn Sie den Namen des Unternehmens eingeben, aus dem Sie kaufen, und klicken Sie dann auf die Schaltfläche "Suchen ", macht einige VBA-Code hinter der Kalkulationstabelle einen UDDI-Aufruf und füllt den Rest des Adressabschnitts aus. Geben Sie z. B. in Microsoft ein, klicken Sie auf "Suchen", und Sie sollten folgendes in den Feldern "Kaufen von" :
.gif)
Abbildung 2. Kauf von Feld
Wenn Sie eine Menge von, z. B. 23, eingeben und dann den Begriff Pear im Beschreibungsfeld eingeben, drücken Sie dann die TAB-TASTE, einige VBA-Codeabfragen einen SOAP-Katalog-Webdienst, um zu sehen, ob es ein übereinstimmende Produkt finden kann, und dann die Details ausfüllt. In diesem Fall habe ich den Katalogwebdienst an die Northwind-Datenbank verkabelt, sodass es folgendes zurückgibt:
.gif)
Abbildung 3. Detaillierter Blick auf den Bestellteil der Kalkulationstabelle
In diesem Fall hat sie auch die Beschreibung ausgefüllt und in einen Link umgewandelt, der Sie zu einer HTML-Seite bringt, die Ihnen alles über dieses Produkt informiert.
Wenn mehr als ein Produkt gefunden wird und keine von ihnen genau mit dem übereinstimmen, was Sie eingegeben haben, wird eine Dropdownliste mit Auswahlmöglichkeiten bereitgestellt. Wenn Sie z. B. tofu eingeben, werden die folgenden Optionen angezeigt:
.gif)
Abbildung 4. Beispiel für mehrere Optionen, die bereitgestellt werden, wenn eine genaue Übereinstimmung nicht gefunden wird
Wenn Sie eine dieser Optionen auswählen, werden die spezifischen Details bereitgestellt.
Wenn Sie fertig sind, klicken Sie auf die Schaltfläche " Senden " und das RosettaNet PIP 3 A4 XML-Bestellformat wird generiert, und die Bestellung wird gesendet.
Wie funktioniert alles?
Sie können den VBA-Code hinter der Kalkulationstabelle durchsuchen, indem Sie zum Menü "Extras" wechseln, Makro auswählen und dann Visual Basic Editor auswählen. Es gibt ein paar Code hinter ThisWorkbook , das auf Änderungen in der Kalkulationstabelle reagiert, insbesondere das Workbook_SheetChange Ereignis ein Zeilenelement auslöscht, wenn Sie die Beschreibung löschen und das Workbook_SheetSelectionChange Ereignis FindProduct () aufruft, wenn Sie das Feld " Beschreibung " im SKU-Feld tabstoppen. Wenn FindProduct eine XMLNode zurückgibt, werden die relevanten Felder aus diesem Knoten abgerufen, um den Rest der Zeilenelementdetails aufzufüllen.
Wie der UDDI-find_business-Aufruf funktioniert, finden Sie in meinem früheren Artikel UDDI: Ein XML-Webdienst. Wenn ein Unternehmen gefunden wird, werden die Adresslinien im Bereich /businessInfo/contact/address/teil der UDDI-Antwort verwendet, um den Adressblock " Kauf aus " aufzufüllen.
Katalogwebdienst
Die Funktion "FindProduct " im Modul "Kataloge" ruft die Katalogdienst-URL mit einem URL-Parameter auf, der den Suchbegriff enthält, um nachzuschlagen. Es erwartet, dass eine SOAP-Antwort zurückgegeben wird und zuerst überprüft wird, ob es mit /Envelope/Body/Fault übereinstimmt, wenn es kein Fehler ist, wird es fortgesetzt, die KatalogQueryResult-Überprüfung> zu öffnen, um zu sehen, ob das <ProductName-Attribut in allen zurückgegebenen Elementen dem angegebenen Ausdruck entspricht. Außerdem wird die Dropdownliste der Auswahlmöglichkeiten weiter unten außerhalb des sichtbaren Bereichs erstellt. Sie können sehen, wie die Dropdownliste funktioniert, indem Sie zum Menü "Daten " wechseln und "Überprüfung" auswählen.
Der Katalogwebdienst ist sehr einfach. Der ASPX-Einstiegspunkt erstellt einfach ein CatalogSearch-Objekt , das in search.cs definiert ist und " Execute" aufruft, indem der HttpResponse-Ausgabedatenstrom wie folgt übergeben wird:
<%@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/>");
}
%>
Die Execute-Methode ist der Ort, an dem der Spaß beginnt. Dies ist sehr einfach SQL Managed Provider Code, der in einem XmlTextWriter umgebrochen ist, der die spezifischen Felder aus der SQL SELECT-Anweisung zurückgibt. So ist es im Grunde eine Zeit, während sie den DataReader durchläuft, das Schreiben an xmlTextWriter wie folgt:
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();
}
Die URL https://localhost/catalog/search.aspx?term=tofu gibt das folgende Ergebnis zurück:
<Envelope xmlns="https://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>
Dies ist die effiziente Möglichkeit, XML mithilfe der .NET Frameworks aus SQL Server herauszuholen. Mit einer sehr groben Messung habe ich ungefähr 80 bis 90 dieser pro Sekunde auf meinem Dell PowerEdge 2400 erhalten.
Schaltfläche "Senden"
Die Funktion SendOrder() lädt ein XML-Dokument aus einer XML-Darstellung eines ausgewählten Zellbereichs in der Tabelle. Dies geschieht mit den folgenden magischen Zeilen von VBA-Code:
With ActiveSheet
Set sourcexml = New MSXML2.DOMDocument
sourcexml.loadXML .Range("B1:N34").value(xlRangeValueXMLSpreadsheet)
End With
Dies gibt einen riesigen Teil von XML zurück, der alles über diesen Zellbereich in der Kalkulationstabelle beschreibt. Im Folgenden handelt es sich um einen Codeausschnitt aus dem Teil von 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">Uncle Bob's Organic Dried
Pears</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">12 - 1 lb pkgs.</Data></Cell>
<Cell ss:StyleID="s37">
<Data ss:Type="Number">690</Data></Cell>
<Cell ss:StyleID="s49"/>
</Row>
</Table>
</Worksheet>
</Workbook>
Anschließend verwenden wir XSL, um dies in das folgende Format zu umwandeln:
<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>Uncle Bob's Organic Dried Pears</Description>
<requestedPrice>
<FinancialAmount>
<GlobalCurrencyCode>USD</GlobalCurrencyCode>
<MonetaryAmount>30</MonetaryAmount>
</FinancialAmount>
</requestedPrice>
</ProductLineItem>
<thisDocumentGenerationDateTime>
<DateTimeStamp>2001-03-15T00:00:00.000</DateTimeStamp>
</thisDocumentGenerationDateTime>
</PurchaseOrder>
Hinweis Dies ist wahrscheinlich keine technisch vollständige Anforderung gemäß RosettaNet PIP 3 A4 Kaufauftragsanforderungsspezifikation, aber Sie erhalten die Idee.
Der Trick, diese Transformation etwas robust zu machen, besteht darin, die wichtigen Zellen zu benennen, von denen wir die Daten ausziehen möchten. Dies erfolgt mit der folgenden XPath-Formatvorlage im XSLT-Transformationsformat:
select="/Workbook/Worksheet/Table/Row/Cell[NamedCell[@ss:Name='City']]
Dieser bestimmte Ausdruck findet das mit Named dem Cell Namen City. Der Rest der Stylesheets ist ziemlich gerade vorwärts. Weitere Informationen finden Sie unter XLToPO.xsl.
Ausprobieren
Um diese Ausführung zu erhalten, müssen Sie MSXML 3.0 installieren und einen Haltevorgang einer Northwind-Datenbank abrufen. Der Democode wird wie folgt an SQL Server verkabelt:
SQLConnection("server=localhost;uid=sa;pwd=;database=northwind");
Möglicherweise müssen Sie diesen Codebit ändern, wenn sich Ihre Northwind-Datenbank an anderer Stelle befindet.
Die PO.xsl-Tabelle erwartet, dass sich der Katalogdienst befindet:
https://localhost/catalog/search.aspx
Sie müssen die Web service search.aspx, search.cs und XLToPO.xsl in einem virtuellen Verzeichnis namens Katalog auf Ihrem lokalen Computer installieren oder die Tabelle an anderer Stelle ändern.
Um das Arbeitsblatt zu bearbeiten, müssen Sie den Schutz deaktivieren, der mithilfe des Untermenüs "Tools/Protection " ausgeführt werden kann.
Nächste Schritte
Idealerweise möchten Sie die Katalogdienstbindungen des Lieferanten in UDDI speichern. Es gibt einige VBA-Code kommentiert, dies für Sie tun wird. Es sucht nach einem erkannten Katalogdienstinfo (by serviceKey) und wenn es gefunden wird, verwendet er dann die accessPoint , die in den ServiceDetails enthalten ist. Die Pseudokatalog-API, die ich in dieser Demo verwende, ist nicht als bekannter Diensttyp in UDDI registriert.
Es wäre eine spaßende Übung, um Office SmartTags zu verwenden, um ähnliche Dinge zu tun. Weitere Informationen finden Sie im https://msdn.microsoft.com/office/ Smart Tags SDK.