XML and Microsoft Office Word 2003: Writing a Trip Report

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

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)

Important

The information set out in this topic is presented exclusively for the benefit and use of individuals and organizations outside the United States and its territories or whose products were distributed by Microsoft before January 2010, when Microsoft removed an implementation of particular functionality related to custom XML from Word. This information may not be read or used by individuals or organizations in the United States or its territories whose products were licensed by Microsoft after January 10, 2010; those products will not behave the same as products licensed before that date or licenses for use outside the United States.

Frank C. Rice, Microsoft Corporation

Paul Cornell, Microsoft Corporation

June 2003

Applies to: Microsoft Office Word 2003

Download odc_wdalpine.exe.

Contents

  • 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

About the Business

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.

Business Problems

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 Solution

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.

Creating the Trip Report Schema

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:

  1. 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 uses http://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:

  2. 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 a tripReport element component of type tripReport_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 another complexType component, and so on. The decision was made to add the suffix _type to simpleType and complexType component names to easily distinguish type name definitions from element name definitions.

  3. 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>
    ...
    
  4. Use the minOccurs and maxOccurs attributes wherever possible to strictly define the number of times that a component occurs.

  5. Use strict data typing wherever possible to leverage the applications' built-in schema validation features.

  6. 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:

  1. Start Visual Studio .NET.

  2. On the File menu, point to New, and click File.

  3. 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.

  4. On the View menu, click Toolbox.

  5. Drag schema components (elements, attributes, simple and complex types, facets, and so on) to the visual designer.

  6. Use the visual designer to customize the schema components.

  7. You can further refine the schema by clicking XML Source on the View menu.

  8. 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:

  1. Start Visual Studio .NET.

  2. On the File menu, point to Open, and click File.

  3. Locate and click the trip_report_sales.xsd file, and click Open.

Using Document Templates to Assist Users in Creating XML Instance Documents

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:

  1. Start Word. A new, blank document appears.

  2. On the Tools menu, click Templates And Add-Ins.

  3. 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:

    1. On the XML Schema tab, click Schema Library.

    2. Click Add Schema.

    3. Locate and click the trip_report_sales.xsd file (include in the download with this article), and click Open.

    4. Click OK twice.

    5. Select the http://www.alpineskihouse.com/schemas/tripReports/salespeople check box, and click OK.

After you've attached the trip report schema:

  1. Add text, formatting, colors, and so on to the document.

  2. Use the XML Structure task pane to add elements to the document.

  3. 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.

  4. 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

Inserting Child Nodes and Their Descendant Nodes into XML Instance Documents

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

Saving XML Instance Documents as Customer-Defined XML Data Only

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 

Using Transforms with XML Instance Documents

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.

Conclusion

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.