Microsoft Office Word 2003 对象模型中新增的 XML 功能

Peter Vogel
PH&V Information Services

适用于:
Microsoft® Office Word 2003

摘要: 使用 Microsoft Office Word 2003 对象模型中的新增 XML 功能借助代码来操作文件。与其他的方法相比,通过 Word 的基于 XML 的功能,您可以利用 XSLT 的能力将文档内容转换为所需的任何格式。您可以将这些转换应用到文档的单个部分以从纯文本创建邮件标签,或者将这些转换作为整体应用到文档以便将电子邮件转换为销售订单。

本页内容

使用 XML 使用 XML
访问文档 访问文档
转换文本 转换文本
小结 小结

使用 XML

在 Microsoft® Office Word 2003 中使用文档的 XML 表示包括两种不同的情况:

  • 通过从架构中添加元素和属性,可以加载 XML 架构并创建文档。作为该种情况的示例,您可能要加载 Docbook 架构(用于创建关于硬件和软件的文档的开放式规范)。 1 显示已加载 Docbook 架构的 Word 2003。

  • 您可以像以前那样使用 Word 2003。还可以选择让代码作为以 WordML(本地 Word XML 格式)术语编写的 XML 文档的一部分与 Word 2003 文档协同工作。

在这两种情况中,您可以访问文档的 XML 表示来提供新增功能。

odc_wd2k3xmlom_fig01

1. Word 2003 中创建 XML 文档

加载架构

要使用 XML 架构,首要的步骤就是加载架构并将其与文档相关联。可以通过来自 Application 对象或 Document 对象的代码来添加架构。

在将架构添加到文档之前,请确保您使用的 Word 版本支持添加架构。Microsoft Office Professional Edition 2003 中的 Microsoft Office Word 2003 核心程序或 Microsoft Office Word 2003 都支持添加自定义架构。如果 Application 对象的 ArbitraryXMLSupportAvailable 属性设置为 True,那么 Word 2003 支持利用 XML 词汇而不是 WordML 来构建文档。

向应用程序对象添加架构

通过使用 XMLNamespaces 集合的 Add 方法,可以将架构添加到 Application 对象。添加后,这些架构可以通过 XML 任务窗格用于用户了。以下代码将 Docbook 架构添加到 Namespaces 集合,如果架构没有定义一个 (dcb),则指定与架构一起使用的命名空间,并且为 Word 2003 在其用户界面 (UI) 中使用的架构指定别名,在此例中,该名称为 Docbook

If Application. ArbitraryXMLSupportAvailable = True Then
Application.XMLNamespaces.Add "c:\Docbook.xsd", "dcb", "Docbook"
End If

添加后,架构由 XMLNamespaces 集合中的 XMLNamespace 对象表示。每个 XMLNamespace 都可以具有一个与它相关联的 XSLT 转换的集合。使用 XSLTransforms 集合的 Add 方法,可以将新的转换添加到 XMLNamespace,同时会创建一个 XMLTransform 对象。必须将包含 XSLT 转换的文件的路径传递到 Add 方法,并且作为可选方案,也可以传递 Word 2003 可以在其 UI 中使用的别名。该示例将 toc.xsl 转换添加到集合中,该集合将作为 Generate TOC 出现在 UI 中:

Application.XMLNamespaces(1).XSLTransforms.Add _
 "c:\transforms\toc.xsl",  "Generate TOC"

使用关联文档的架构

在将架构添加到 Application 对象的 XMLNamespaces 集合后,可以使用 XMLNamespace 对象的 AttachToDocument 方法将该架构与文档相关联。该代码将 XMLNamespaces 集合中的第二个架构与当前文档相关联:

Application.XMLNamespaces(2).AttachToDocument ActiveDocument

通过 Document 对象的 XMLSchemaReferences 集合,可以使用 XMLSchemaReferences 集合的 Add 方法将架构直接添加到文档。通过引用在将架构添加到 Application 对象的 XMLNamespaces 集合时建立的 NamespaceURI,该代码将 Docbook 架构添加到文档的架构引用:

ActiveDocument.XMLSchemaReferences.Add "dcb"

或者,可以不使用 XMLNamespaces 集合,而直接将架构添加到文档中。这也会将架构添加到 Application 对象的 XMLNamespaces 集合中:

ActiveDocument.XMLSchemaReferences.Add "dcb",  _
"Docbook",  "C:\shemas\Docbook.xsd"

XMLSchemaReference 对象的 Add 方法的第一个参数就是与架构一起使用的命名空间(在此例中,为 dcb)。第二个参数为 UI 中使用的架构提供一个别名。第三个参数是到要加载的架构的路径。

访问文档

有两种方法可以用于访问 Word 2003 中文档的 XML 表示:

  • 提取 XML 文本

  • 访问组成 XML 文档对象模型的 XML 节点

提取文本

Word 2003 文档始终由 WordML 标记组成。在 Word 2003 中使用架构时,架构的标记会与 WordML 标记相互混合。WordML 标记控制文档在 Word 2003 中的显示方式。

通过 RangeSelection 对象的 XML 属性,可以提取文档的 XML 文本。XML 属性始终返回完整的 WordML 文档,包括 WordML 根元素 (wordDocument)。例如,以下代码从活动文档的第二段中提取 XML:

ActiveDocument.Paragraphs(2).Range.XML

作为示例,该示例文本只包含两个短段落:

The quick brown fox jumps over the lazy dog.
A rolling stone gathers momentum.

提取第一段的 WordML 表示会返回很多文本 — 超过 3,000 个字符。XML 属性返回的文档非常大,因为它不仅包括选定范围的文本,还包括影响文本的所有上下文信息:文档中样式的定义、有关文档字体的信息、文档的页面尺寸和边距等等。

XML 属性返回的文档内,构成内容的段落都位于 WordML body元素内部。body 元素文档包含<t>标记(文本)、<r>标记(文本的运行)以及<p>标记(段落)中文档的内容。同时出现在正文中的<sectPr>标记保存着定义文档部分(例如页面尺寸和边距)的元素。

如果基于某些 XML 架构创建文档,那么组成该架构的标记将会与允许 Word 2003 操作文本的 WordML 标记相互混合。作为示例,这是 Docbook 文档的开始:

<book><title>Office MSXML</title></book>

检索该文档的 XML 属性会返回在其正文标记中带有如下代码的文档:

<w:body>
<wx:sect>
<ns0:book>
<w:p>
<ns0:title>
<w:r><w:t> Office MSXML</w:t></w:r>
</ns0:title>
</w:p>
</ns0:book>
. . .

要使 WordML 和 Docbook 标记分开,使用前缀 ns0 标记 Docbook 该前缀将这些标记限制在 wordDocument 元素上定义的Docbook 命名空间。

<w:wordDocument
xmlns:w="https://schemas.microsoft.com/office/word/2003/wordml"
. . .various other namespace declarations. . .
xmlns:ns0="dcb">

为了检索所用架构的元素,XML 属性会接受允许删除 WordML 标记的一个参数(称为 DataOnly)。当 DataOnly 设置为 True 时,以下代码只返回文档中的非 WordML XML 标记:

ActiveDocument.Paragraphs(1).Range.XML(True)

对于示例 Docbook 文档,返回的 XML 类似如下所示:

<?xml version="1.0" standalone="no"?>
<book xmlns="DocBook">
<title>Office MSXML</title>
</book>

提取 XML 节点

在利用架构创建的文档中,还可以使用 RangeSelectionDocument 对象的 XMLNodes 属性,将文档作为一系列 XML 节点进行访问。XMLNodes 集合包含 XMLNode 对象,如果您使用 MSXML 工具集中的 DOM 分析器,则该对象的方法和属性看起来会非常熟悉。该示例主要关注添加到 Word 2003 对象模型的 XMLNode 对象的功能,尽管 MSXML 的某些通用方法和属性对 Word 2003 开发人员也非常有用。

在前面显示的示例 Docbook 文档中有两个节点:一个用于 book 元素,一个用于 title 元素。以下代码会检索 title 元素:

Dim nd As XMLNode
Set nd = ActiveDocument.XMLNodes(2)

node 对象的属性包括节点的内容(文本)、节点的名称 (BaseName) 以及节点的命名空间 (NamespaceURI)。

在大多数情况下,只需要在文档中处理其中一些节点。Document 对象的 SelectNodes 方法使用 XPath 语句来指定节点,从而可以提取您想要的节点。当利用命名空间搜索元素时,必须将命名空间的前缀包括在标记名称中。SelectNodes 方法的第二个参数通过使用与 XML 文档中相同的语法来定义命名空间。不管嵌套的深度如何,该示例都会找到 Docbook 命名空间中该文档的所有 TITLE 元素,该命名空间将 ns0 作为其前缀:

Dim nds As XMLNodes
Dim nd As XMLNode
Set nds = ActiveDocument.SelectNodes("//ns0:title",  _
"xmlns:ns0='dcb' ")
For Each nd In nds
   MsgBox "Value for title tags: " & nd.Text
Next

XMLNodes 集合的第一个成员位于位置 1,因此这是使用 For. . .Next 循环处理所有成员的所要使用的代码:

For ing = 1 To nds.Count
    Set nd = nds.Item(ing)
    MsgBox "Value for title tags: " & nd.Text
Next

为了提高搜索的速度,可以将 SelectNodes 方法的第三个参数设置为 False,这样会导致搜索跳过所有文本节点(在 XML 元素的打开和关闭标记之间的文本内容)。如果您并不搜索节点的内容,同时文档包含很多文本(Word 2003 文档通常如此),那么设置这个参数可以显著提高搜索速度。

对于要添加到文档中的任何特定命名空间,可以通过 XMSchemaReference 对象的 NamespaceURI 属性检索命名空间。重新编写之前的代码以使用 NamespaceURI 属性,可得到如下代码:

Set nds = ActiveDocument.SelectNodes("//ns0:title", "xmlns:ns0=' " & _
ActiveDocument.XMLSchemaReferences(1).NamespaceURI  & _
"' ")

Word 2003 新增的基于 XML 的技术可以顺利地合并来自 Word 以前版本的 Word 对象。例如,检索到某个节点后,就可以通过检索 XMLNode 对象的 Range 属性,使用该节点表示的 Word 对象。

Dim rng As Range
Set rng = nd.Range

还可获得较大的 Word 2003 文档内有关节点位置的某些反馈。例如,节点的 Level 属性指示出节点是否为可显示的文本 (Level = wdXMLNodeLevelInline),或者为段落的一部分 (Level = wdXMLNodeLevelParagraph)。Level 属性还指示出节点是否为表格行或单元格的一部分。

更改文档

可以使用 InsertXML 方法或 XMLNodes 集合来更新文档。两种方法都允许操作文档的内容来创建新的资料。

更新文本

通过 RangeSelection 对象的 InsertXML 方法,可以利用插入 XML 文本的任意字符串来更新文档。如果更新没有使用架构的 WordML 文档,则必须插入完整的 WordML 文档。幸运的是,基本 WordML 文档包含五个标记(wordDocument、body、p、r、t)以及 WordML 命名空间。例如,该文档在最小的 WordML 文档中包含如下单个字符串:

<w:wordDocument xmlns:w=
'https://schemas.microsoft.com/office/word/2003/wordml'>
<w:body>
    <w:p>
<w:r>
<w:t>Hello, World.</w:t>
</w:r>
   </w:p>
</w:body>
</w:wordDocument>

作为示例,在以下文本中,我们假设选择了单词 jumps

The quick brown fox jumps over the lazy dog.

以下代码将当前选择 (jumps) 替换为单词 leaps

Selection.Range.InsertXML _
"<w:wordDocument xmlns:w=" & _
"'https://schemas.microsoft.com/office/word/2003/wordml'>" & _
"<w:body><w:p><w:r><w:t>leaps</w:t></w:r></w:p></w:body>" & _
"</w:wordDocument>"

更新节点

对于使用架构的文档,通过 XMLNode 对象的 Range 属性的 XML 属性,可以添加新的 XML。将新资料插入文档时,需要组合 WordML 标记(以便将文本显示在 Word 中)和架构的标记。然而,为了使代码更易读,接下来的示例忽略了 WordML 标记。

示例 Docbook 文档的标题为“Office XML”。对该 Docbook 文档的一个更改可以插入与 title 标记一起使用的 subtitle 标记,可以得到以下结构:

<?xml version="1.0" standalone="no"?>
<book xmlns="DocBook">
<title>Office MSXML<subtitle>XML Objects</subtitle></title>
</book>

插入 XML 时前缀是必需的,以便该标记会限制到正确的架构。要确保插入的 XML 正确地形成,必须在要插入的 XML 内定义前缀(及其命名空间)。以下代码将 subtitle 标记插入到文档:

ActiveDocument.XMLNodes(2).Range.InsertXML  _
"<ns0:subtitle xmlns:ns0='dcb'>XML Objects</ns0:subtitle>"

将 XML 插入到节点会替换该节点的所有现有内容。使用之前的代码将新内容插入到 title 节点中,以替换现有内容(如 2 所示):

<ns0:book>
<ns0:title>
<ns0:subtitle>XML Objects</ns0:subtitle>
</ns0:title>
</ns0:book>

odc_wd2k3xmlom_fig02

2. title 元素内容替换为 subtitle 元素

如果您的目标是添加到现有内容(而不是替换它),则必须向父节点添加一个子节点。使用节点的 ChildNodes 集合的 Add 方法,传递新节点所属的节点和命名空间的名称(Word 2003 会负责为该节点分配适当的前缀),您可以添加节点。以下示例会添加一个名为 subtitle 的子节点,作为 Docbook 命名空间的一部分。在创建该节点后,代码就会将字符串“XML Objects”分配给节点的 Text 属性:

Dim nd As XMLNode
Set nd = ActiveDocument.XMLNodes(2).ChildNodes.Add ("subtitle", _
"dcb")
nd.Text = "XML Objects"

生成的代码包含以下标记集(请参见 3):

<ns0:book>
<ns0:title>Office MSXML<ns0:subtitle>XML Objects</ns0:subtitle>
</ns0:title>
</ns0:book>

odc_wd2k3xmlom_fig03

3. subtitle 子元素添加到 title 元素

再次运行代码会在刚刚添加的子标题后添加另一个子标题。

添加子节点不会受到限制。使用 XMLNodes 集合的 Add 方法,可以在现有文档的任意位置添加节点。在何处添加节点取决于所用的对象类型。例如,如果使用 ActiveDocument 对象,如此例中所示,新节点将会被插入到光标位置:

ActiveDocument.XMLNodes.Add "subtitle", "dcb"

XMLNodes 集合也可以从任意节点的 Range 属性获得。由于是从文档中的现有节点中使用,添加新节点后,它会包括所有已经存在的子节点。例如,该文档会在 chapter 元素内嵌套一段文本。

<ns0:book xmlns:ns0='dcb'>
<ns0:chapter>My Paragraph</ns0:chapter>
</ns0:book>

要将段落节点添加到章节(并且将该段落文本放在新创建的段落中),可以使用以下带有章节的 Range 属性的代码:

Dim ndBook As XMLNode
Set nd = ActiveDocument.XMLNodes(1)
nd.Range.XMLNodes.Add "para", "dcb"

结果就是下面的 XML:

<ns0:book xmlns:ns0='dcb'>
<ns0:chapter>
<ns0:para>My Paragraph</ns0:para>
</ns0:chapter>
</ns0:book>

转换文本

InsertXML 方法的实际功能在于该方法的第二个参数,它接受到包含 XSLT 的文件的路径名称。传递路径名后,InsertXML 方法会使用文件中的 XSLT 代码在第一个参数中处理 XML,然后将结果插入到文档中。

例如,该 Docbook 文档包含两个 chapter 元素和一个称为 toc 的空目录元素(对于这些示例,会包括相关的 WordML 标记以确保在插入文本后,由 Word 2003 显示该文本):

<ns0:book>
   <ns0:toc/>
   <ns0:chapter>
      <ns0:title>
<w:p><w:r><w:t>Chapter 1</w:t></w:r></w:p>
</ns0:title>
   <ns0:chapter>
<ns0:chapter>
      <ns0:title>
<w:p><w:r><w:t>Chapter 2</w:t></w:r></w:p>
</ns0:title>
   <ns0:chapter>
</ns0:book>

以下 XSLT 会找到所有章节 title 标记,并生成包含 TOCENTRY 和 TITLE 标记的 Docbook 目录:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
xmlns:w='https://schemas.microsoft.com/office/word/2003/wordml'
xmlns:ns0='dcb'>

<xsl:template match="/">
<w:wordDocument>
<w:body>
   <xsl:for-each select="//ns0:chapter">
      <ns0:tocchap><ns0:tocentry>
      <w:p>
<w:r>
<w:t>
<xsl:value-of select="w:p/ns0:title"/>
</w:t>
</w:r>
</w:p>
      </ns0:tocentry></ns0:tocchap>
   </xsl:for-each>
</w:body>
</w:wordDocument>

</xsl:template>

</xsl:stylesheet>

在通过 InsertXML 方法完成的所有更新中,您必须插入完整的 wordDocument 文档,这样样式表也可以添加 wordDocument 和 BODY 元素。要求使用<WordML>、<p> 、<r> 和<t>标记,以便在 Word 2003 中显示 TOCENTRY 元素中的文本。

下一段代码会检索文档中到 TOC 节点的引用。然后,代码调用该节点的 InsertXML 方法,传递该文档的 XML 文本以及包含 XSLT 的文件的路径。

Dim ndToc As XMLNode
Set ndToc = ActiveDocument.SelectSingleNode("//ns0:toc", _
"xmlns:ns0='dcb')
ndToc.Range.InsertXML ActiveDocument.Range.XML, _
"c:/Transforms/toc.xsl"

结果是生成构建自文档中的 chapter 元素、带有目录的 Docbook 文档。

如果要转换整个文档,而不是转换选定节点的内容,您可以调用 Document 对象的 TransformDocument 方法。TransformDocument 方法接受两个参数:

  • 到带有 XSLT 代码的文件的路径

  • 指示是处理整个文档还是仅处理非 WordML 标记的布尔值。该参数设置为 True 会忽略 WordML 标记。

不需要对这些方法的调用中的路径进行硬编码,您就可以使用指定命名空间的 XSLTransforms 集合的 XSLTransform 对象。XSLTransform 对象的 Location 属性提供到包含 XSLT 的文件的路径名。如果重新编写前面的代码以使用 Location 属性,您将获得以下代码:

ndToc.Range.InsertXML ActiveDocument.Range.XML, _
Application.XMLNamespaces(1).XSLTransforms(1).Location

转换现有文档的内容只是应用 XSLT 的其中一种用法。您可以像阅读 XML 文档那样简单地使用 XSLT 就可以将文档转换为 WordML 格式(或其他任何 XML 格式)。例如,Microsoft Office Access 2003 支持以 XML 格式导出其表格。简单的 XSLT 转换允许文件格式转换为 WordML 以便作为 Word 2003 文档或者转换为 Docbook 格式,如果这种格式是该信息的最终格式。

响应更改

Word 2003 也会在执行 XML 操作时引发事件。Document 对象将引发两个新的、与 XML 相关的事件:

  • XMLAfterInsert:添加新节点时引发。该事件例程被传递到新节点的引用。

  • XMLBeforeDelete:删除节点时引发。一个到 Range 对象的引用会传递到该事件例程,该对象包括部分要删除的文档以及对要删除的节点的引用。

一个布尔变量会传递到两个事件,如果在撤消或重复操作过程中添加或删除节点,则将该变量设置为 True

Word 2003 Application 对象将激发两个新的、与 XML 相关的事件:

  • XMLValidationError:只要文档中出现验证错误就会引发。单个参数会被传递到该事件:到出错节点的引用。

  • XMLSelectionChange:只要选择新节点就引发。四个参数会传递到该事件例程:新选定资料的 WordSelection 对象、对失去焦点和获得焦点的节点的引用以及原因代码。

要使用这些事件,您需要设置全局变量并将它们分配给适当的对象。以下代码作为类模块的 Initialize 事件的一部分完成此操作:

Dim WithEvents wrd As Application
Dim WithEvents doc As Document
Private Sub Class_Initialize()
   Set doc = ActiveDocument
   Set wrd = Application
End Sub

在某些其他事件中,例如 Word 2003 中的 AutoOpen 例程,必须创建类模块。完成后,类模块中的代码可以捕获 XML 事件。

选择更改

您可以出于各种原因更改当前选择的节点:移动光标、插入新节点和删除节点。并不是所有这些活动都会生成选择更改事件。例如,您可以让光标位于一个子元素的 end 元素和另一个子元素的 start 元素之间。在这种情况下,当前选择的节点是两个子节点的父节点。如果在相同的父节点内的两个不同子节点之间单击,那么选定的节点不会更改并且不会触发任何选择更改事件。

如果确实引发了选择更改事件,那么作为最后一个参数传递到 XMLSelectionChange 事件的原因代码会指示出选择更改的原因。原因代码可具有三个值:

  • wdXMLSelectionChangeReasonMove:因为在文档中移动光标选择不同节点而导致选择发生变化。这时,在文档首次打开后,您首先选择一个节点,OldXMLNode 的属性为 Nothing

  • wdXMLSelectionChangeReasonDelete:因为节点被删除导致选择发生变化。OldXMLNode 始终为 Nothing。并不是所有删除都会引发选择更改。例如,如果当前选定的节点是父节点,删除子节点则不会生成选择更改事件。使用 XMLBeforeDelete 事件来捕获所有删除。

  • wdXMLSelectionChangeReasonInsert:因为插入新节点导致选择发生变化。新节点在 NewXMLNode 中传递。还可以使用 XMLAfterInsert 事件来捕获节点插入。

作为示例,当插入 TOC 元素时,以下代码会运行创建带有目录的代码:

Private Sub doc_XMLAfterInsert(ByVal NewXMLNode As XMLNode, _
ByVal InUndoRedo As Boolean)
If NewXMLNode.BaseName = "toc" Then
NewXMLNode.Range.InsertXML ActiveDocument.Range.XML,  _
"c:/Transforms/toc.xsl"
End If
End Sub

验证文档

使用 XML 架构的其中一个优点在于根据架构定义用于文档中的标记来验证任意特定文档的能力。使用架构时,如果用户插入新标记,Word 2003 就会在以下两个位置标记冲突:XML 任务窗格和文档本身中。

生成的消息是常规 XML 错误消息(首次插入某个元素时的典型消息是“Some required content is missing”)。这些消息不会为用户提供实际的指导,即不能提供消除验证错误确切应该执行什么操作。

Word 2003 使您可以自定义在文档中为任意节点生成的消息。对于任意节点,您可以调用节点的 SetValidationError 方法,传递 ValidationStatus 常量、要显示在验证错误上的消息以及指示消息是否自动清除的标记。

在此例中,当验证错误出现在 TOC 元素上时,该代码会添加一则新消息。该消息会提供有关带有目录的 Docbook 中所要求的详细信息:

Private Sub wrd_XMLValidationError(ByVal XMLNode As XMLNode)
If XMLNode.BaseName = "toc" Then
XMLNode.SetValidationError wdXMLValidationStatusCustom, _
"You must insert a title or tocentry element", True
End If
End Sub

您可以控制何时发生验证。Word 2003 的默认值是根据当前使用的架构验证更改文档文本的每个用户操作。因此,管理验证的第一步是关闭 Word 的自动验证:

ActiveDocument.XMLSchemaReferences.AutomaticValidation = False

还可以通过调用 XMLSchemaReferencesValidate 方法来验证整个文档,或者通过调用它的 Validate 方法只验证单个节点。以下代码只验证第二个节点及其子节点:

ActiveDocument.XMLNodes(2).Validate

为了使 Validate 方法运行,您必须将 XMLSchemaReferencesAutomaticValidation 属性再次设置为 True

在调用 Validate 方法后,您可以检查任意节点的 ValidateStatus 方法以确定是否发现了错误。还可以处理文档的 XMLSchemaViolations 集合中的节点以发现错误中的所有节点。以下代码会显示与具有验证错误的每个节点相关联的错误消息:

Dim nd As XMLNode
For Each nd In ActiveDocument.XMLSchemaViolations
   Msgbox nd.ValidationErrorText
Next

保存文档

当完成文档后,您希望保存它。如果尚未完成文档就可保存文档,则您可能希望设置文档所用架构的 AllowSaveAsXMLWithoutValidation 属性。这样可以防止只由于文档的所有必需部分尚未填写完毕而收到错误消息。

Document 对象的 Save 方法仍然会保存完整的 Word 2003 文档。将 Document 对象的 XMLSaveDataOnly 属性设置为 True 会导致 Word 2003 仅将与架构相关联的标记保存到文档的文件中。将 Document 对象的 XMLUseXSLTWhenSaving 设置为 True 会导致 XSLT 转换应用到文档并保存转换的输出。如果将 XMLUseXSLTWhenSaving 设置为 True,也必须将 XMLSaveThroughXSLT 属性设置为包含 XSLT 代码的文件的路径名。最后,您必须将文档的格式设置为 XML。

例如,以下代码使用 ConvertToFOMM.XSL 样式表仅保存文档中添加的、与架构相关的标记:

ActiveDocument.XMLSaveDataOnly = True
ActiveDocument.XMLSaveThroughXSLT = _
"c:\Transforms\ConvertToHTML.XSL"
ActiveDocument.XMLUseXSLTWhenSaving = True
ActiveDocument.SaveAs MyDocument.HTM, wdFormatXML

应该在使用 XSLT 转换保存该文档之前,根据其架构对该文档进行验证。尽管可以将 SchemaReferences 集合的 AllowSaveAsXMLWithoutValidation 属性设置为 True,但是根据无效文档处理 XSLT 样式表的结果将无法预计。

利用该代码创建的只有 XML 数据的文档并不包括原始 Word 2003 文档包括的所有信息。所有 WordML 标记都会丢失,而且通常情况下,新文档中的数据是原始 Word 2003 文档中的数据的子集。因此,您还希望保存原始的 Word 2003 文档以保留其中的所有信息。实现上述想法的最简单的方法就是将 XSMLSaveDataOnlyUseXSLTWhenSaving 属性设置为 False,并且执行另一个保存:

ActiveDocument.XMLSaveDataOnly = False
ActiveDocument.XMLUseXSLTWhenSaving = False
ActiveDocument.Save

小结

Word 2003 通过将 XML 集成到其对象模型中,获得了很多功能。这种集成提供了创建应用程序所需要的工具,这些应用程序利用 XML 来支持文档创建。通过利用自定义代码扩展 Word 2003 的基本功能,您可以为用户提供新级别的支持。

作者简介

Peter Vogel 一位 Office 和 .NET 开发方面的顾问。他著有 Visual Basic Object and Component Handbook(Prentice Hall PTR,2000, ISBN:0-13023-0731),并担任 Smart Access 时事通讯的编辑。

转到原英文页面