Integrating Office XP Smart Tags with the Microsoft .NET Platform
Jim Powell and Taylor Maxwell
Microsoft® Office XP
Summary: This article focuses on developing a Microsoft Office XP smart tag to utilize an XML Web service on the .NET platform. (10 printed pages)
Smart tags are similar to hyperlinks because they can link content in Microsoft® Office-based documents or Web pages with related content hosted on servers, on Web sites, and in files. Smart tags can also be extended to automate custom applications. Simple smart tag solutions can be created using a text editor such as Notepad and distributed as XML files. More advanced smart tag solutions rely on the Microsoft Smart Tags 1.0 type library in Microsoft Office XP, with these solutions distributed as dynamic-link libraries (DLLs). By integrating calls to XML Web services (via the SOAP Toolkit) into these COM objects, these smart tags can take advantage of the any or all of the available XML Web services, which may be created and published by using the Microsoft .NET Framework SDK on an intranet or the Internet.
For this article, readers should have familiarity with Office XP smart tags, the Microsoft .NET platform, and Microsoft Visual Basic®. The required operating system for this article is Microsoft Windows® 2000. The required operating system for the XML Web service is Microsoft Windows 2000 Server.
This article assumes that the developer is familiar with the Office XP Smart Tag SDK 1.1.
This article also assumes that the developer is familiar with the SOAP Toolkit. For more information, see Developing a Web Service: Up and Running with the SOAP Toolkit for Visual Studio and Web Services: Building Reusable Web Components with SOAP and ASP.NET.
Installation of the sample application is detailed in the rxinfo Smart Tag Demo Install.doc file included with the sample download. It requires the following steps:
- Installation of the prescription XML Web service.
- Adding the rxinfo database to Microsoft SQL Server™ 2000 and connecting to it.
- Registering the rxinfo.dll component on the client computer (if desired, this may be the same computer hosting the XML Web service).
- Setting security settings on Microsoft Word 2002 and Microsoft Excel 2002 to Medium to allow the applications to run components that are unsigned. Note that these settings are only intended for ease of use with the sample application. All production smart tags should be signed and the security settings for Word 2002 and Excel 2002 should be set to High.
The key points of this article will be the highlighting of the code within the smart tag recognizer interface and action interface that utilize the published methods to call into the desired XML Web service.
Figure 1 illustrates the integration of the local smart tag DLL with the XML Web service available over HTTP.
Figure 1. The RxInfo architecture
Let's see how the smart tag developer can leverage existing functionality already available on the Web in the form of XML Web services. All that's needed to call a SOAP-compliant XML Web service is to send a SOAP request message that conforms to the published Web Services Description Language (WSDL). In the SOAP Toolkit 2.0, the Services Description Language (SDL) has been replaced with the WSDL and the Web Services Meta Language (WSML). WSDL and WSML files describe the interfaces to a service and expose COM objects to SOAP clients.
To query an XML Web service for its published methods, simply add the cmd string to the .asmx file. For example:
After running this query, we see that the prescription XML Web service provides the following Web methods (along with their required parameters and response types):
Table 1. Prescription Web Services Description Language (published Web methods)
|Web method||Request parameters||Response type|
|Get Interaction||(DrugName1, DrugName2)||(dataset)|
First, let's look at the List Web method, which returns a listing of all the drugs in the database. Notice that it does not require any parameters. Upon the class initialization, we'll call this method to create the response document using the Document Object Model (DOM). DOM is an in-memory (cache) tree representation of an Extensible Markup Language (XML) document that enables you to navigate and edit the document.
The Show Web method performs exactly as named. The user inputs a drug name into the document and the recognizer matches the name to the list built in its initialization call to the List Web method.
Finally, there is the GetInteractions Web method, which requires two drug names as input and returns a listing of negative interactions between the drugs.
Typically, the smart tag will use a static text file or an internal database call to build the list of recognized terms. In this case, however, we'll use an XML Web service to build this list (along with its hosted database directory of recognized drugs). As part of the initialization routine for the recognizer, we'll create a node list of recognized drugs by parsing through the response document from the GetDrugs Web method.
Next, we'll create a variable for the node list.
Private ndDrugs As MSXML.IXMLDOMNodeList
When the application starts, it initializes the smart tag.
Private Sub Class_Initialize() Dim dom As MSXML.DOMDocument Dim bSuccess As Boolean Dim sServerName As String
This registry key points the smart tag to the Web server hosting the service.
sServerName = GetSettingString(HKEY_CURRENT_USER, _ "SOFTWARE\MICROSOFT\AppDirName\rxinfo", "WebServer")
It then creates the response document.
Set dom = New MSXML.DOMDocument bSuccess = dom.Load("http://" & sServerName & "/Prescription/DrugInfo.asmx/List")
Finally, it populates the node list by traversing through the response document.
If Not bSuccess Then MsgBox "Web Service is missing" Else Set ndDrugs = dom.getElementsByTagName("NewDataSet") End If
In the action interface, that we'll start to invoke verbs that are actually calls to Web methods described by the WSDL of the XML Web service.
From the ISmartTagAction_VerbCount property, we see three supported verbs:
Private Property Get ISmartTagAction_VerbCount(ByVal SmartTagName As String) As Long ' For a given smart tag type, how many verbs do we support? If (SmartTagName = "schemas-office-com /AppDirName/prescriptions#info") Then ISmartTagAction_VerbCount = 3 End If End Property
Now, let's get the VerbID property by passing the SmartTagName argument (we'll use the VerbID property later in the ISmartTagAction_InvokeVerb method):
Private Property Get ISmartTagAction_VerbID(ByVal SmartTagName As String, _ ByVal VerbIndex As Long) As Long ISmartTagAction_VerbID = VerbIndex End Property This property returns a caption for the smart tag that will be displayed as the smart tag action: Private Property Get ISmartTagAction_VerbCaptionFromID(ByVal VerbID As Long, _ ByVal ApplicationName As String, ByVal LocaleID As Long) As String Select Case VerbID Case 1 ISmartTagAction_VerbCaptionFromID = "Get Drug Information" Case 2 ISmartTagAction_VerbCaptionFromID = "Check for Bad Interactions" Case 3 ISmartTagAction_VerbCaptionFromID = "Insert Instructions" End Select End Property
This property returns the VerbName argument for the smart tag that will be displayed as the smart tag action:
Private Property Get ISmartTagAction_VerbNameFromID(ByVal VerbID As Long) As String Select Case VerbID Case 1 ISmartTagAction_VerbNameFromID = "Information" Case 2 ISmartTagAction_VerbNameFromID = "Interactions" Case 3 ISmartTagAction_VerbNameFromID = "InsertInstructions" End Select End Property
Let's look at the method named ISmartTagAction_InvokeVerb. We are passing it the VerbID argument returned from the ISmartTagAction_VerbID property:
Public Sub ISmartTagAction_InvokeVerb(ByVal VerbID As Long, _ ByVal ApplicationName As String, ByVal Target As Object, _ ByVal Properties As SmartTagLib.ISmartTagProperties, _ ByVal Text As String, ByVal XML As String) Dim dom As New MSXML.DOMDocument Dim sServerName As String Dim i As Integer Dim sXML As String Dim sErrorPosition As String On Error GoTo eAction sErrorPosition = "Checking Application" sServerName = GetSettingString(HKEY_CURRENT_USER, _ "SOFTWARE\MICROSOFT\ AppDirName\rxinfo", "WebServer")
Here we define the type of Range object returned dependant upon the calling application:
If ApplicationName = "Word.Application.10" Then Dim aWord As Word.Application Dim rWord As Word.Range Dim wTags As Word.SmartTags Set aWord = New Word.Application Set rWord = Target ElseIf ApplicationName = "Excel.Application.10" Then Dim rExcel As Excel.Range Dim oWorksheet As Excel.Worksheet Dim eTags As Excel.SmartTags Set rExcel = Target Set oWorksheet = rExcel.Worksheet End If
We have passed the VerbID argument into this method. Each Select Case VerbID statement calls on the published Web methods that correlate with the VerbID argument. Let's look at the first Case statement, and then you'll extend this example to the remaining Case statements:
Select Case VerbID Case 1 'Information. Dim ndDrug As MSXML.IXMLDOMNode dom.async = False dom.resolveExternals = False
The recognizer has previously found a match for a drug name. The following is the actual SOAP call to the Web method:
sXML = "http://" & sServerName & "/prescription/druginfo.asmx/" & _ "Show?sDrugName=" & Text sErrorPosition = "Loading Drug Information" dom.Load sXML Set ndDrug = dom.getElementsByTagName("NewDataSet")
Here, we parse the response document and load it into an informational message box:
MsgBox ndDrug.Item(0).childNodes(0).childNodes(1).Text & vbCr & vbCr & _ "Brand: " & ndDrug.Item(0).childNodes(0).childNodes(2).Text & vbCr & vbCr & _ "Dosage: " & ndDrug.Item(0).childNodes(0).childNodes(4).Text & vbCr & vbCr & _ "Contraindications: " & ndDrug.Item(0).childNodes(0).childNodes(3).Text
It is more useful to load the response document back into the calling document. In Case 3, we'll actually parse the response document back into the Word document:
Case 3 If ApplicationName = "Word.Application.10" Then Dim ndDrugInfo As MSXML.IXMLDOMNodeList Set rWord = Target dom.async = False dom.resolveExternals = False sXML = "http://" & sServerName & "/Prescription/DrugInfo.asmx/" & _ "Show?sDrugName=" & Text sErrorPosition = "Loading Drug Information" dom.Load sXML Set ndDrugInfo = dom.getElementsByTagName("NewDataSet") rWord.Application.Selection.Select rWord.Application.Selection.MoveRight Unit:=wdCell sErrorPosition = "Moving Position" sErrorPosition = "Inserting contraindications" rWord.Application.Selection.InsertAfter _ ndDrugInfo.Item(0).childNodes(0).childNodes(3).Text End If
In sum, we've shown how to:
- Query for published Web methods that are to be leveraged in the smart tag solution.
- Build a node list in the recognizer action from a response document of an XML Web service.
- Map the action interface verbs to Web methods and parse the response document back into the calling application.
As the number of published XML Web services grows, so will the number of opportunities for smart tag developers to leverage this pre-built functionality in their solutions—without taking on the added tasks of development and maintenance of these services.