Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Frank C. Rice and Paul Cornell
Microsoft Corporation
June 2003
Applies to:
Microsoft® Office Word 2003
Summary: Many companies have sales representatives that spend a considerable amount of time on the road at customer sites. Explore some of the ways that you can take advantage of the XML features of Word to make creating and filing trip reports easier. You will also see how to create a Word template and how to transform data from format to another. (24 printed pages)
Download odc_wdalpine.exe.
About the Business
Business Problems
The Solution
Creating the Trip Report Schema
Using Document Templates to Assist Users in Creating XML Instance Documents
Inserting Child Nodes and Their Descendant Nodes into XML Instance Documents
Saving XML Instance Documents as Customer-Defined XML Data Only
Using Transforms with XML Instance Documents
Conclusion
Alpine Ski House is a West-coast outdoor-equipment manufacturer. In addition to making skis, Alpine Ski House has begun making snowboards and snowshoes. Next year, Alpine Ski House plans to add a winter clothing line. In preparation for this new venture, several of Alpine Ski House's 15 sales representatives have been visiting ski resorts across the United States to pitch their idea to clothing stores and gift shops near the ski slopes. During these visits, sales representatives record their findings in a series of trip reports, which are e-mailed back each evening to Alpine Ski House's headquarters. Alpine Ski House's marketing team wants to aggregate all of the sales representatives' trip reports into daily, weekly, and monthly overall trip reports, as well as a final report at the end of the winter season.
Although all of the Alpine Ski House's sales representative carry laptops with the Microsoft® Office System installed, the sales representatives have created their trip reports in the past using a combination of Microsoft Word documents, e-mail messages, Microsoft Excel spreadsheets, Microsoft PowerPoint® presentations, and the like. This has resulted in the marketing team wasting a lot of time copying and pasting the trip reports' information into summary reports. Marketing also has to do a lot of follow-up conversations with sales representatives when key information is missing from the trip reports. This wastes a lot of time for both marketing and sales representatives.
The proposed solution must use Word as the trip report writing application. The trip reports must require the sales representatives to enter the trip details that marketing requires to create their summary reports. The trip report template must not take a lot of skill to fill out. The trip reports must be able to be transformed into other summary report formats. Finally, the trip reports must be flexible to add special trip details or other business insights that deviate from marketing's requirements if needed.
The solution consists of the following components:
- The trip report XML schema.
- A trip report Word template.
- A transform that summarizes the trip report for the marketing department.
From an operational perspective, this solution must:
- Given a document template, reference the appropriate schemas and transforms with as little user intervention as possible.
- Allow users to save instance documents as XML data only without any Word XML document schema markup (although customer-defined transforms can be applied while saving XML data).
- Allow users to insert new visit report sections, with the required descendant nodes, as children of the visits report section.
- Allow users to insert new visited place report sections, with the required descendant nodes, as children of existing visit report sections.
- Allow users to insert new contact report sections, with the required descendant nodes, as children of existing contacts report sections.
After consulting with Alpine Ski House marketing department, it was determined that the salespeople needed to capture the following information for their marketing database.
- The salesperson's name and e-mail address.
- The date that the visits were conducted.
- A general summary comprising all of the visits for that date.
- For each visited geographical area, an overall visit summary, and the places visited in that area, including site names, site summaries, site addresses, and people contacted at each site.
- For each contact, a name, e-mail address, street address, phone number, fax number, mobile phone number, pager number, other means to reach the contact, the visit start and end times, and any other notes about the contact.
Based on this information, the following customer-defined schema was created:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema
targetNamespace=
"http://www.alpineskihouse.com/schemas/tripReports/salespeople"
elementFormDefault="qualified"
xmlns=
"http://www.alpineskihouse.com/schemas/tripReports/salespeople"
xmlns:mstns=
"http://www.alpineskihouse.com/schemas/tripReports/salespeople"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="placeContact_type">
<xs:annotation>
<xs:documentation>If you visit multiple people at a location
you can record a separate contact for each person
visited.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="placeContactName" type="xs:string" />
<xs:element name="placeContactEmail" type="xs:string"
minOccurs="0" maxOccurs="1" />
<xs:element name="placeContactAddress" type="xs:string"
minOccurs="0" maxOccurs="1" />
<xs:element name="placeContactOfficePhone" type="telephone_type"
minOccurs="0" maxOccurs="1" />
<xs:element name="placeContactOfficeFax" type="telephone_type"
minOccurs="0" maxOccurs="1" />
<xs:element name="placeContactMobilePhone" type="telephone_type"
minOccurs="0" maxOccurs="1" />
<xs:element name="placeContactPager" type="telephone_type"
minOccurs="0" maxOccurs="1" />
<xs:element name="placeContactOtherCommunication" type="xs:string"
minOccurs="0" maxOccurs="1" />
<xs:element name="placeContactStartTime" type="xs:time"
minOccurs="0" maxOccurs="1" />
<xs:element name="placeContactEndTime" type="xs:time"
minOccurs="0" maxOccurs="1" />
<xs:element name="placeContactNotes" type="xs:string"
minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="placeContacts_type">
<xs:sequence>
<xs:element name="placeContact" type="placeContact_type"
minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="visitedPlace_type">
<xs:sequence>
<xs:element name="placeName" type="xs:string" />
<xs:element name="placeAddress" type="xs:string"
minOccurs="0" maxOccurs="1" />
<xs:element name="placeSummary" type="xs:string"
minOccurs="0" maxOccurs="1" />
<xs:element name="placeContacts" type="placeContacts_type"
minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="visitedPlaces_type">
<xs:sequence>
<xs:element name="visitedPlace" type="visitedPlace_type"
minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="visit_type">
<xs:sequence>
<xs:element name="visitLocation" type="xs:string" />
<xs:element name="visitSummary" type="xs:string"
minOccurs="0" maxOccurs="1" />
<xs:element name="visitedPlaces" type="visitedPlaces_type"
minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>You can break individual visits up into
multiple "visitedPlaces" elements if
needed.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="tripReport_type">
<xs:sequence>
<xs:element name="salespersonName" type="xs:string" />
<xs:element name="salespersonEmail" type="xs:string" />
<xs:element name="reportDate" type="xs:date" />
<xs:element name="reportSummary" type="xs:string"
minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>A summary of all of the day's
reports.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="visits" type="visits_type"
minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>You can break the day's visits up into
multiple "visit" elements if
needed.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="visits_type">
<xs:sequence>
<xs:element name="visit" type="visit_type"
minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:element name="tripReport" type="tripReport_type">
<xs:annotation>
<xs:documentation>Defines an Alpine Ski House trip
report.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:simpleType name="telephone_type">
<xs:annotation>
<xs:documentation>Accepts United States phone number patterns
only.</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:pattern value="([0-9][0-9][0-9])
[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
The schema follows this basic pattern:
<tripReport>
<salespersonName>
<salespersonEmail>
<reportDate>
<reportSummary>
<visits>
<visit>
<visitLocation>
<visitSummary>
<visitedPlaces>
<visitedPlace>
<placeName>
<placeAddress>
<placeSummary>
<placeContacts>
<placeContact>
<placeContactName>
<placeContactEmail>
<placeContactAddress>
<placeContactOfficePhone>
<placeContactOfficeFax>
<placeContactMobilePhone>
<placeContactPager>
<placeContactOtherCommunication>
<placeContactStartTime>
<placeContactEndTime>
<placeContactNotes>
Some of the key schema design decisions include the following:
Define extensible namespaces. When the W3C XML Schemas recommendation was in its infancy, organizations would create some odd-looking namespaces that didn't seem to follow any pattern, such as
uri:schemas-myCompany-com#mySchema, schemas.myCompany.com.mySchema
, and so on. By convention, organizations are encouraged to use their Internet URL, followed by an internally-agreed-upon naming convention. A namespace should look very much like an Internet address. For example, Alpine Ski House useshttp://www.alpineskihouse.com/schemas
as its base namespace, followed by the schema's purpose, followed by which group will primarily use the schema. Following this naming convention, Alpine Ski House could create schema names such as:Use a single element component to define the root element, and use a series of
complexType
components to define all of the root element's descendant elements. For example, the root element is defined in atripReport
element component of typetripReport_type
, as follows:... <xs:element name="tripReport" type="tripReport_type" /> ...
The tripReport_type is defined as a complexType component as follows:
<xs:complexType name="tripReport_type"> <xs:sequence> <xs:element name="salespersonName" type="xs:string" /> <xs:element name="salespersonEmail" type="xs:string" /> <xs:element name="reportDate" type="xs:date" /> <xs:element name="reportSummary" type="xs:string" minOccurs="0" maxOccurs="1" /> <xs:element name="visits" type="visits_type" minOccurs="0" maxOccurs="1" /> </xs:sequence> </xs:complexType> ...
The
visits_type
is defined in yet anothercomplexType
component, and so on. The decision was made to add thesuffix _type
tosimpleType
andcomplexType
component names to easily distinguish type name definitions from element name definitions.Embed documentation directly into the schema. Every component allows a child annotation element, which in turn allows a child documentation element, that can contain documentation, for example:
... <xs:element name="tripReport" type="tripReport_type"> <xs:annotation> <xs:documentation>Defines an Alpine Ski House trip report.</xs:documentation> </xs:annotation> </xs:element> ...
Use the
minOccurs
andmaxOccurs
attributes wherever possible to strictly define the number of times that a component occurs.Use strict data typing wherever possible to leverage the applications' built-in schema validation features.
Restrict the range of input values wherever possible to leverage the applications' built-in data input validation features.
... <xs:complexType name="placeContact_type"> <xs:annotation> <xs:documentation>If you visit multiple people at a location you can record a separate contact for each person visited. </xs:documentation> </xs:annotation> <xs:sequence> <xs:element name="placeContactName" type="xs:string" /> <xs:element name="placeContactEmail" type="xs:string" minOccurs="0" maxOccurs="1" /> <xs:element name="placeContactAddress" type="xs:string" minOccurs="0" maxOccurs="1" /> <xs:element name="placeContactOfficePhone" type="telephone_type" minOccurs="0" maxOccurs="1" /> ... ... <xs:simpleType name="telephone_type"> <xs:annotation> <xs:documentation>Accepts United States phone number patterns only.</xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> <xs:pattern value="([0-9][0-9][0-9]) [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]" /> </xs:restriction> </xs:simpleType> </xs:schema> ...
The trip report schema was created with Microsoft Visual Studio® .NET as follows:
- Start Visual Studio .NET.
- On the File menu, point to New, and click File.
- In the New File dialog box, open the General folder in the left pane, click the XML Schema icon in the right pane, and click Open.
- On the View menu, click Toolbox.
- Drag schema components (elements, attributes, simple and complex types, facets, and so on) to the visual designer.
- Use the visual designer to customize the schema components.
- You can further refine the schema by clicking XML Source on the View menu.
- When you're finished creating the schema, click Save on the File menu, and save the .xsd file to the desired location.
For help with using schema syntax, click inside of any schema component in Schema or XML view, and on the Help menu, click Dynamic Help.
To view the trip report schema in Visual Studio .NET:
- Start Visual Studio .NET.
- On the File menu, point to Open, and click File.
- Locate and click the trip_report_sales.xsd file, and click Open.
To assist users in creating XML instance documents, all of the document templates are visually enhanced with things like colors, shading, and text formatting. Users can save the XML instance documents without visual formatting details, leaving the customer-defined XML data unaltered in the saved XML instance documents.
To create a document template with embedded customer-defined XML:
Start Word. A new, blank document appears.
On the Tools menu, click Templates And Add-Ins.
If the http://www.alpineskihouse.com/schemas/tripReports/salespeople check box is visible, select it, and click OK.
If the http://www.alpineskihouse.com/schemas/tripReports/salespeople check box is not visible:
- On the XML Schema tab, click Schema Library.
- Click Add Schema.
- Locate and click the trip_report_sales.xsd file (include in the download with this article), and click Open.
- Click OK twice.
- Select the http://www.alpineskihouse.com/schemas/tripReports/salespeople check box, and click OK.
After you've attached the trip report schema:
Add text, formatting, colors, and so on to the document.
Use the XML Structure task pane to add elements to the document.
Save the file as a Word document template (.dot).
Note If you want to allow users to create valid XML documents without concern for any text formatting interspersed with XML components in the template, before you save the document template, in the XML Structure task pane, click XML Options, select the Ignore Mixed Content check box, and click OK. If the user saves the XML document with XML data only, the text formatting, as well as any other content outside of the embedded elements, will not be saved with the XML document. If the user saves the XML document to the Word XML document schema format, both the embedded elements and the text formatting will be saved with the XML document.
To view the finished version of the trip report document template, use Word to open the TripReportTemplate.dot file (include in the download with this article).
Figure 1. TripReportTemplate.dot file
To insert child nodes along with the child nodes' descendant nodes, the document template has attached Microsoft Visual Basic® for Applications (VBA) code. When the document template is loaded, a custom toolbar is created with commands to insert child nodes and their Visual descendant nodes (see Figure 2).
Figure 2. Custom toolbar
These commands are only active when the user's insertion point is within a specific node so that users can't accidentally insert nodes in the wrong places in the documents. To tidy up after itself, when the document template is closed, the associated toolbar is deleted.
The VBA code is as follows:
Public WithEvents gwdApp As Word.Application
Private Const TOOLBAR_NAME = "Trip Report Actions"
Public gcbToolbar As Office.CommandBar
Dim wdApp As New DeclareWordApp
Public Sub CreateToolbar()
Dim cbToolbar As Office.CommandBar
Dim blnToolbarExists As Boolean
Dim strCaptions(1 To 4) As String
Dim strOnActions(1 To 4) As String
blnToolbarExists = False
' If the toolbar exists, don't create a duplicate one.
For Each cbToolbar In Application.CommandBars
If cbToolbar.Name = TOOLBAR_NAME Then
blnToolbarExists = True
End If
Next cbToolbar
If blnToolbarExists = False Then
Set gcbToolbar = Application.CommandBars.Add(TOOLBAR_NAME)
strCaptions(1) = "New Visit"
strOnActions(1) = "InsertItem.InsertNewVisit"
strCaptions(2) = "New Place"
strOnActions(2) = "InsertItem.InsertNewPlace"
strCaptions(3) = "New Contact"
strOnActions(3) = "InsertItem.InsertNewContact"
strCaptions(4) = "Save As XML"
strOnActions(4) = "SaveDoc.SaveDocAsXML"
Call AddButtons(gcbToolbar, 4, strCaptions, strOnActions)
gcbToolbar.Visible = True
End If
End Sub
Public Sub DeleteToolbar()
Dim cbToolbar As Office.CommandBar
For Each cbToolbar In Application.CommandBars
If cbToolbar.Name = TOOLBAR_NAME Then
cbToolbar.Delete
End If
Next cbToolbar
End Sub
Private Function AddButtons(ByRef cbToolbar As Office.CommandBar, _
ByVal intNumButtons As Integer, ByRef strCaptions() As String, _
ByRef strOnActions() As String) As Office.CommandBar
Dim cbToolbarButton As Office.CommandBarButton
Dim intCounter As Integer
intCounter = 1
Do While intCounter <= intNumButtons
Set cbToolbarButton = cbToolbar.Controls.Add(msoControlButton)
With cbToolbarButton
.Style = msoButtonCaption
.Caption = strCaptions(intCounter)
.OnAction = strOnActions(intCounter)
.Enabled = True
End With
intCounter = intCounter + 1
Loop
Set AddButtons = cbToolbar
End Function
Private Sub Document_Open()
Set gwdApp = Word.Application
Call CreateToolbar
End Sub
Private Sub Document_Close()
Call Toolbar.DeleteToolbar
Set wdApp = Nothing
End Sub
Public Sub InsertNewVisit()
On Error Resume Next
Call InsertNewVisitHandler2(Selection.XMLParentNode)
End Sub
Public Sub InsertNewPlace()
On Error Resume Next
Call InsertNewPlaceHandler2(Selection.XMLParentNode)
End Sub
Public Sub InsertNewContact()
On Error Resume Next
Call InsertNewContactHandler2(Selection.XMLParentNode)
End Sub
Public Sub InsertNewVisitHandler2(ByRef objNode As Word.XMLNode)
On Error Resume Next
Dim objVisitedPlacesNode As Word.XMLNode
Dim objVisitedPlaceNode As Word.XMLNode
Dim objPlaceContactNode As Word.XMLNode
If objNode.BaseName = "visits" Then
Dim objPlaceNode As Word.XMLNode
objNode.ChildNodeSuggestions(1).Insert ' visit
objNode.ChildNodes(1).ChildNodeSuggestions(1).Insert ' visitLocation
Selection.MoveRight
objNode.ChildNodes(1).ChildNodeSuggestions(2).Insert ' visitSummary
Selection.MoveRight
objNode.ChildNodes(1).ChildNodeSuggestions(3).Insert ' visitedPlaces
Set objVisitedPlacesNode = objNode.ChildNodes(1).ChildNodes(3) ' visitedPlaces
Set objVisitedPlaceNode = InsertNewPlaceHandler2(objVisitedPlacesNode)
Set objPlaceContactNode = InsertNewContactHandler2(objVisitedPlaceNode)
Else
MsgBox "You must click inside of a visits element first."
End If
End Sub
Public Function InsertNewPlaceHandler2(ByRef objNode As Word.XMLNode) As Word.XMLNode
On Error Resume Next
If objNode.BaseName = "visitedPlaces" Then
Dim objContactsNode As Word.XMLNode
Dim objContactNode As Word.XMLNode
objNode.ChildNodeSuggestions(1).Insert ' visitedPlace
objNode.ChildNodes(1).ChildNodeSuggestions(1).Insert ' placeName
Selection.MoveRight
objNode.ChildNodes(1).ChildNodeSuggestions(2).Insert ' placeAddress
Selection.MoveRight
objNode.ChildNodes(1).ChildNodeSuggestions(3).Insert ' placeSummary
Selection.MoveRight
objNode.ChildNodes(1).ChildNodeSuggestions(4).Insert ' placeContacts
Set objContactsNode = objNode.ChildNodes(1).ChildNodes(4) ' placeContacts
Set objPlaceContactNode = InsertNewContactHandler2(objContactsNode)
Else
MsgBox "You must click inside of a visitPlaces element first."
End If
End Function
Public Function InsertNewContactHandler2(ByRef objNode As Word.XMLNode) As Word.XMLNode
On Error Resume Next
If objNode.BaseName = "placeContacts" Then
objNode.ChildNodeSuggestions(1).Insert ' placeContact
objNode.ChildNodes(1).ChildNodeSuggestions(1).Insert ' placeContactName
Selection.MoveRight
objNode.ChildNodes(1).ChildNodeSuggestions(2).Insert ' placeContactEmail
Selection.MoveRight
objNode.ChildNodes(1).ChildNodeSuggestions(3).Insert ' placeContactAddress
Selection.MoveRight
objNode.ChildNodes(1).ChildNodeSuggestions(4).Insert ' placeContactOfficePhone
Selection.MoveRight
objNode.ChildNodes(1).ChildNodeSuggestions(5).Insert ' placeContactOfficeFax
Selection.MoveRight
objNode.ChildNodes(1).ChildNodeSuggestions(6).Insert ' placeContactMobilePhone
Selection.MoveRight
objNode.ChildNodes(1).ChildNodeSuggestions(7).Insert ' placeContactPager
Selection.MoveRight
objNode.ChildNodes(1).ChildNodeSuggestions(8).Insert ' placeContactOtherCommunication
Selection.MoveRight
objNode.ChildNodes(1).ChildNodeSuggestions(9).Insert ' placeContactStartTime
Selection.MoveRight
objNode.ChildNodes(1).ChildNodeSuggestions(10).Insert ' placeContactEndTime
Selection.MoveRight
objNode.ChildNodes(1).ChildNodeSuggestions(11).Insert ' placeContactNotes
Else
MsgBox "You must click inside of a placeContacts element first."
End If
End Function
To address the requirement that users can save instance documents as customer-defined XML data only without any Word XML document schema markup, the document template has attached VBA code. This code allows users to easily save the customer defined XML data while the document template is active.
The VBA code is as follows:
Public Sub SaveDocAsXML()
On Error GoTo SaveDocAsXML_Err
ActiveDocument.XMLSaveDataOnly = True
ActiveDocument.SaveAs , wdFormatXML
SaveDocAsXML_End:
Exit Sub
SaveDocAsXML_Err:
Select Case Err.Number
Case 6119 ' XML not valid.
MsgBox Err.Description & ". Please correct the " & _
"document and try again."
GoTo SaveDocAsXML_End
Case Else
MsgBox Err.Number & " " & Err.Description
GoTo SaveDocAsXML_End
End Select
End Sub
When marketing reports their findings to the Alpine Ski House board of directors, they only want to expose the following information:
- The salesperson's name and the date that the visits were conducted.
- The overall summary of all visits.
- The geographical areas visited with the overall visit summary.
- The place names and place summaries in each geographical area.
- The contacts names and contact notes for each place visited.
The following XSL file can be run against the TripReportTemplate.dot to create an XML file with only the above information. Copy the following into a file with an .xsl extension:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sr="http://www.alpineskihouse.com/schemas/" & _
"tripReports/salespeople"
xmlns:mr="http://www.alpineskihouse.com/" & _
"schemas/tripReports/marketing">
<xsl:template match="/sr:tripReport">
<mr:tripReport>
<xsl:apply-templates/>
</mr:tripReport>
</xsl:template>
<xsl:template match="sr:salespersonName">
<mr:salesperson>
<xsl:value-of select="."/>
</mr:salesperson>
</xsl:template>
<xsl:template match="sr:salespersonEmail"/>
<xsl:template match="sr:reportDate">
<mr:date>
<xsl:value-of select="."/>
</mr:date>
</xsl:template>
<xsl:template match="sr:reportSummary">
<mr:summary>
<xsl:value-of select="."/>
</mr:summary>
</xsl:template>
<xsl:template match="sr:visits">
<mr:visits>
<xsl:for-each select="./sr:visit">
<mr:visit>
<mr:location>
<xsl:value-of select="./sr:visitLocation"/>
</mr:location>
<mr:summary>
<xsl:value-of select="./sr:visitSummary"/>
</mr:summary>
<mr:places>
<xsl:apply-templates select= & _
"./sr:visitedPlaces"/>
</mr:places>
</mr:visit>
</xsl:for-each>
</mr:visits>
</xsl:template>
<xsl:template match="sr:visitedPlaces">
<xsl:for-each select="./sr:visitedPlace">
<mr:place>
<xsl:apply-templates/>
</mr:place>
</xsl:for-each>
</xsl:template>
<xsl:template match="sr:placeName">
<mr:name>
<xsl:value-of select="."/>
</mr:name>
</xsl:template>
<xsl:template match="sr:placeAddress"/>
<xsl:template match="sr:placeSummary">
<mr:summary>
<xsl:value-of select="."/>
</mr:summary>
</xsl:template>
<xsl:template match="sr:placeContacts">
<mr:contacts>
<xsl:for-each select="./sr:placeContact">
<mr:contact>
<xsl:apply-templates/>
</mr:contact>
</xsl:for-each>
</mr:contacts>
</xsl:template>
<xsl:template match="sr:placeContactName">
<mr:name>
<xsl:value-of select="."/>
</mr:name>
</xsl:template>
<xsl:template match="sr:placeContactEmail"/>
<xsl:template match="sr:placeContactAddress"/>
<xsl:template match="sr:placeContactOfficePhone"/>
<xsl:template match="sr:placeContactOfficeFax"/>
<xsl:template match="sr:placeContactMobilePhone"/>
<xsl:template match="sr:placeContactPager"/>
<xsl:template match="sr:placeContactOtherCommunication"/>
<xsl:template match="sr:placeContactStartTime"/>
<xsl:template match="sr:placeContactEndTime"/>
<xsl:template match="sr:placeContactNotes">
<mr:notes>
<xsl:value-of select="."/>
</mr:notes>
</xsl:template>
</xsl:stylesheet>
You can use the transform to change an XML document's actual contents. With the XML document open, when you click Save As on the File menu, select the Apply Transform check box, click Transform, select a transform, click Open, and then click Save. The transform is applied to a copy of the XML document's contents as the XML document is saved.
In this article, we examined a fictitious company, the Alpine Ski House, and how they used the XML features of Word to create a system the allowed their sales representatives to record, file, and transform the information compiled from sales trips. The application used XML template where the representative entered data into preformatted fields which could then be saved as XML data only or saved with a transform to convert the data into a summarized format. The representative could also easily add addition elements to the template as needed with a custom toolbar. Using similar features in Word and the other Microsoft Office applications can reduce the effort and duplication common in legacy systems that are often put together piecemeal.