在 Open XML WordprocessingML 中使用编号列表
**摘要:**了解 Open XML 中的列表。Word 2010 文档经常包含编号列表和点符列表。WordprocessingML 的这一领域当然复杂。编号列表和点符列表包含许多功能,每项功能都由一组不同用户使用。
上次修改时间: 2012年1月3日
适用范围: Office 2010 | Open XML | Visual Studio Tools for Microsoft Office | Word 2007 | Word 2010
本文内容
概述
简单编号列表标记
简单点符列表标记
多级列表标记
链接到样式的编号标记
用新的编号格式替代多级列表中的编号格式
替代多级列表中的编号格式,并创建多级列表格式
处理 w:startOverride 元素
定义列表样式
列表项后缀的备选项
处理 w:lvlRestart 元素
处理 w:isLgl 元素
组合列表项文本的算法
结论
其他资源
**发布时间:**2010 年 3 月
供稿人:Eric White(该链接可能指向英文页面), Microsoft Corporation
目录
概述
简单编号列表标记
简单点符列表标记
多级列表标记
链接到样式的编号标记
用新的编号格式替代多级列表中的编号格式
替代多级列表中的编号格式,并创建多级列表格式
处理 w:startOverride 元素
定义列表样式
列表项后缀的备选项
处理 w:lvlRestart 元素
处理 w:isLgl 元素
组合列表项文本的算法
概述
实施从 Open XML 字处理文档到 HTML 的转换时,其中一个值得关注的问题是如何准确转换编号列表和点符列表。您必须编写特定代码来处理它们,因为它们会影响文档中包含的文本,但是该文本并不直接位于标记中。如果您要准确地提取文档的文本,则必须处理一些元素和属性来组合正确文本。
备注
本文同时适用于 Microsoft Word 2010 和 Microsoft Office Word 2007。
点符列表和编号列表很复杂,这也是很正常的。编号列表和点符列表具有许多功能,每项功能都由一组不同的用户使用。这些功能由标记中的元素表示。不过,您没有必要注意所有元素。标记的某些方面之所以存在只是为了影响用户界面,当您确定编号项或点符项的文本表示形式时,则不必注意那些元素。本文只介绍您在处理编号项和点符项时必须了解的一些基本要素。
谈论编号标记最简单的方法是将标记与 Word 的用户界面关联。您只须关心可以通过以下三个按钮进行的文档修改:
图 1. 编号列表的工具栏按钮
WordprocessingML 编号标记有相当多的间接寻址。标记中的这种间接寻址有三种模式:
简单编号列表或点符列表的直接编号
基于样式的编号,即标题 1 在第一缩进级别,标题 2 在第二缩进级别。
命名的编号样式
本文分别探讨这些模式。
简单编号列表标记
下图显示创建简单编号列表时生成的标记。
图 2. 创建简单编号列表
为准确讨论标记,我们必须区分编号列表或点符列表的两个方面。对于每个编号项或点符项,都有两个组成部分:列表项和段落文本。
图 3. 点符列表项
我们必须区分这些项目,因为列表项是我们需要为每个段落组合的内容。此外,列表项还有单独的格式设置标记。编号列表也存在这种区别。
图 4. 编号列表项
下图显示简单编号列表或点符列表的间接寻址。
图 5. 简单编号列表或点符列表的间接寻址
接下来,探讨以下简单编号列表的标记。
图 6. 简单编号列表
主文档部件中的标记如下所示。
<w:p>
<w:pPr>
<w:pStyle w:val="ListParagraph"/>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="1"/>
</w:numPr>
</w:pPr>
<w:r>
<w:t>Paragraph one.</w:t>
</w:r>
</w:p>
w:numPr 元素包含我们所关心的编号元素。w:ilvl 元素是一个从零开始的数字,指示缩进级别。编号项位于最低缩进级别,以便 w:ilvl 的值为零。w:numId 元素是编入 w:num 元素的索引,位于编号部件中。
重要说明 |
---|
w:numId 可以包含 0 值 ,这是一个特殊值,指示已从此级别的样式层次结构中删除编号。处理此标记时,如果 w:val='0',则段落不含列表项。 |
编号部件标记如下所示。
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<w:numbering xmlns:w="https://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:abstractNum w:abstractNumId="0">
<!-- These affect the user interface. We can ignore them. -->
<w:nsid w:val="5FE17486"/>
<w:multiLevelType w:val="hybridMultilevel"/>
<w:tmpl w:val="1084E0BA"/>
<w:lvl w:ilvl="0"
w:tplc="0409000F">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:lvlText w:val="%1."/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="720"
w:hanging="360"/>
</w:pPr>
</w:lvl>
<w:lvl w:ilvl="1"
w:tplc="04090019"
w:tentative="1">
<w:start w:val="1"/>
<w:numFmt w:val="lowerLetter"/>
<w:lvlText w:val="%2."/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="1440"
w:hanging="360"/>
</w:pPr>
</w:lvl>
<!-- a number of other w:lvl elements elided -->
</w:abstractNum>
<w:num w:numId="1">
<w:abstractNumId w:val="0"/>
</w:num>
</w:numbering>
主文档部件中 w:numPr 元素中的索引引用 w:num 元素。在本例中,该元素包含单个元素,即 w:abstractNumId,它引用出现在它前面的 w:abstractNum 元素。w:abstractNum 元素包含设置列表项格式所需的信息。请注意,w:abstractNum 元素不包含段落的格式信息(缩进信息除外,该信息同时涉及列表项和段落)。段落本身的格式与往常一样存储在主文档部件和样式部件中。有三个元素(w:nsid 元素、w:multiLevelType 元素和 w:tmpl 元素)只影响字处理应用程序中的用户界面,您可以忽略它们。
备注
本文的其余部分从标记列表中去除了这些元素。
w:lvl 元素和 w:lvl 子元素定义列表项的每个缩进级别的格式。同时还存在其他 w:lvl 元素(已从列表中删除),用于定义第二级和更高级别上每个级别的列表项格式。w:lvl 元素的 w:tplc 属性和 w:tentative 属性的存在只是为了用户界面。我会从其他列表中删除它们。
提示
从 w:num 元素到 w:abstractNum 元素的间接寻址允许使用替代列表项格式的标记。下文中将会讨论此标记。
您真正需要关注的元素是 w:lvl 元素的子元素:w:start 元素、w:numFmt 元素、w:lvlText 元素、w:lvlJc 元素和复杂元素 w:pPr。
w:start 元素指定缩进级别的起始编号。您是从 0、1 还是其他数字开始计数?不允许使用负数(而且这样做也没有多大意义)。
在本例中,w:numFmt 元素指示文档在列表项中将一个十进制数用作缩进级别 0,将一个小写字母用作缩进级别 1。该元素有相当多的选项:
点符
十进制数 (1, 2, 3)
零加十进制数 (01, 02, 03)
大写罗马数字 (I, II, III)
小写罗马数字 (i, ii, iii)
大写字母 (A, B, C)
小写字母 (a, b, c)
序数 (1st, 2nd, 3rd)
基数字 (One, Two Three)
序数字 (First, Second, Third)
备注
此处不包含用于其他语言的其他选项。各种亚洲语言都有此列表中未涵盖的编号系统。
您将 w:lvlText 元素作为模板来构造列表项。对于级别 0,本例使用"%1.",它指示无论确定的是什么 w:numFmt 文本,最小缩进项都会替换格式字符串中的 %1。对于级别 1,本例使用"%2.",它指示无论确定的是什么文本,第一个缩进都会替换 %2。请注意,对于 w:lvl 元素,您使用从零开始的索引指定缩进级别,而在 w:lvlText 模板中,您使用从一开始的索引指定替换标记。这很合理。w:lvl 元素仅供开发人员使用,从零开始的索引对开发人员而言较为容易,而模板由用户使用和指定,因此从一开始的索引较有意义。这两个元素非常强大,使您能够创建几乎满足任何需要的分层列表格式。下文中提供了有关这两个元素的更多示例。
重要说明 |
---|
对于点符列表,即使 w:lvltext 元素包含替换标记(如 %1 和 %2),替换标记也不会被级别编号替换。这不影响我们的代码,因为 w:lvlText 元素不含替换标记。 |
w:lvlJc 元素控制列表项是右对齐还是左对齐以及其他选项。下面显示使用文本的编号项目的左对齐与右对齐间的区别。虽然在本例中很容易看到区别,但如果您的点符列表或编号列表使用了数字,则会很难发现区别。
图 6. 对齐的列表项
最后,有一些适用于列表项的段落属性,例如指定缩进和悬挂缩进。
w:lvl 元素也可以包含适用于列表项的运行属性。如果将列表项的字体改为 Courier,则它看上去如下所示。
图 7. 使用 courier 字体格式的列表项
下面是包含用于定义列表项字体的运行属性的 w:lvl 元素示例。
<w:lvl w:ilvl="0">
<w:start w:val="1"/>
<w:numFmt w:val="ordinalText"/>
<w:lvlText w:val="%1)"/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="720"
w:hanging="360"/>
</w:pPr>
<w:rPr>
<w:rFonts w:ascii="Courier New"
w:hAnsi="Courier New"
w:hint="default"/>
</w:rPr>
</w:lvl>
像往常一样,主文档部件中的段落还包含对样式的引用。
<w:p>
<w:pPr>
<w:pStyle w:val="ListParagraph"/>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="1"/>
</w:numPr>
</w:pPr>
<w:r>
<w:t>One</w:t>
</w:r>
</w:p>
我们可以在样式部件中找到该样式,它指定段落文本的格式。
<w:style w:type="paragraph"
w:styleId="ListParagraph">
<w:name w:val="List Paragraph"/>
<w:basedOn w:val="Normal"/>
<w:pPr>
<w:ind w:left="720"/>
<w:contextualSpacing/>
</w:pPr>
</w:style>
这是应用了样式的段落的标记的典型模式。
简单点符列表标记
本节介绍创建简单点符列表时生成的标记,如下图所示。
图 8. 创建简单符号项目列表
简单符号项目列表的标记间接寻址模式与简单编号列表的模式相同。
对于简单点符列表,主文档部件 (document.xml) 包含与简单编号列表完全相同的段落。
<w:p>
<w:pPr>
<w:pStyle w:val="ListParagraph"/>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="1"/>
</w:numPr>
</w:pPr>
<w:r>
<w:t>One</w:t>
</w:r>
</w:p>
下面是编号部件的示例。
<w:abstractNum w:abstractNumId="0">
<w:lvl w:ilvl="0">
<w:start w:val="1"/>
<w:numFmt w:val="bullet"/>
<w:lvlText w:val="o"/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="720"
w:hanging="360"/>
</w:pPr>
<w:rPr>
<w:rFonts w:ascii="Symbol"
w:hAnsi="Symbol"
w:hint="default"/>
</w:rPr>
</w:lvl>
<!-- several w:lvl elements elided -->
<w:num w:numId="1">
<w:abstractNumId w:val="0"/>
</w:num>
</w:numbering>
此处的 w:lvlText 元素的 w:val 属性被另存为字符 0xB7,这是此级别的点符(来自 Symbol 字体)。此示例的要点在于您可以编写一种通用方法来组合列表项的文本,并且此方法同时适用于编号列表和点符列表。
w:start 元素不影响列表项,因为 w:lvlText 模板元素不包含替换标记(例如 %1 和 %2),但即使包含,我们也不会替换该标记。
多级列表标记
您可以看到此框架很容易实现多级列表。您可以将源文档更改为如下图所示。
图 9. 简单多级列表
主文档部件中的段落如下所示。第二段的 w:ilvl 元素设置为"1"。
<w:p>
<w:pPr>
<w:pStyle w:val="ListParagraph"/>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="1"/>
</w:numPr>
</w:pPr>
<w:r>
<w:t>One</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="ListParagraph"/>
<w:numPr>
<w:ilvl w:val="1"/>
<w:numId w:val="1"/>
</w:numPr>
</w:pPr>
<w:r>
<w:t>Two</w:t>
</w:r>
</w:p>
在本例中,没有修改编号和样式部件。
链接到样式的编号标记
有一种编号功能可为用户带来很大方便,但会使标记变得更加复杂。您可以将一种样式链接到一种编号类型和级别,然后用一个列表项表示该样式的所有段落。典型的例子是将标题 1 样式链接到第一个缩进级别,将标题 2 样式链接到第二个缩进级别。使用这种方法的文档看起来如下图所示。
图 10. 链接到样式的编号
链接到样式的编号的标记间接寻址模式如下所示。
图 11. 链接到样式的编号的间接寻址
在本例中,主文档部件不包含与编号相关的任何标记。
<w:p>
<w:pPr>
<w:pStyle w:val="Heading1"/>
</w:pPr>
<w:r>
<w:t>Overview of Numbering</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading2"/>
</w:pPr>
<w:r>
<w:t>Markup of a Simple Numbered List</w:t>
</w:r>
</w:p>
标题 1 样式的样式部件中的标记包含对编号部件中 w:num 元素的引用。
<w:style w:type="paragraph"
w:styleId="Heading1">
<w:name w:val="heading 1"/>
<w:basedOn w:val="Normal"/>
<w:pPr>
<w:numPr>
<w:numId w:val="1"/>
</w:numPr>
<w:spacing w:before="480"
w:after="0"/>
<w:outlineLvl w:val="0"/>
</w:pPr>
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi"
w:eastAsiaTheme="majorEastAsia"
w:hAnsiTheme="majorHAnsi"
w:cstheme="majorBidi"/>
<w:b/>
<w:bCs/>
<w:color w:val="365F91"
w:themeColor="accent1"
w:themeShade="BF"/>
<w:sz w:val="28"/>
<w:szCs w:val="28"/>
</w:rPr>
</w:style>
编号部件类似如下:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<w:numbering xmlns:w="https://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:abstractNum w:abstractNumId="0">
<w:lvl w:ilvl="0">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:pStyle w:val="Heading1"/>
<w:lvlText w:val="%1"/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="432"
w:hanging="432"/>
</w:pPr>
</w:lvl>
<w:lvl w:ilvl="1">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:pStyle w:val="Heading2"/>
<w:lvlText w:val="%1.%2"/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="576"
w:hanging="576"/>
</w:pPr>
</w:lvl>
<!-- Remaining w:lvl elements elided -->
</w:abstractNum>
<w:num w:numId="1">
<w:abstractNumId w:val="0"/>
</w:num>
</w:numbering>
w:pStyle 元素链接回样式部件中的样式。通过查找与段落样式匹配的 w:pStyle 元素,可确定缩进级别。父 w:lvl 复杂元素定义缩进级别。与往常一样,您组合来自 w:lvl 元素的其他子元素的列表项文本。
用新的编号格式替代多级列表中的编号格式
通过使用新的编号格式,您可以替代多级列表中任何级别的编号格式。这会影响标记。要创建此标记,请先创建一个多级列表:
图 12. 创建多级列表
然后选择一个段落,并定义一种新的编号格式:
图 13. 替代编号格式
在"定义新编号格式"对话框中,更改某些方面。本例中我们更改了标题 2,使列表项是后跟一个括号的基数:"One)"
图 14. "定义新编号格式"对话框
主文档部件的标记现在看起来如下所示:
<w:p>
<w:pPr>
<w:pStyle w:val="Heading1"/>
</w:pPr>
<w:r>
<w:t>Paragraph One</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading2"/>
<w:numPr>
<w:ilvl w:val="1"/>
<w:numId w:val="2"/>
</w:numPr>
</w:pPr>
<w:r>
<w:t>Paragraph Two</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading3"/>
</w:pPr>
<w:r>
<w:t>Paragraph Three</w:t>
</w:r>
</w:p>
编号部件中的标记现在有两个 w:num 元素,每个元素指向它们各自的抽象编号格式:
<w:num w:numId="1">
<w:abstractNumId w:val="1"/>
</w:num>
<w:num w:numId="2">
<w:abstractNumId w:val="0"/>
</w:num>
然后可以像往常那样处理抽象编号标记。此处的要点是当您使用样式设置编号格式时,标记将遵循本节中详述的间接寻址。如果该样式的段落包含 w:numPr 元素,这将替代从抽象编号格式到样式的链接。
替代多级列表中的编号格式,并创建多级列表格式
用户可以替代多级列表中任一级别的编号格式,创建多级列表格式,这会影响标记。要创建此标记,请先创建一个多级列表。
图 15. 创建多级列表
然后选择一个段落,并定义新的多级列表。
图 16. 定义新的多级列表
在"定义新多级列表" 对话框中,更改列表级别的某些方面。我的示例更改了格式,使第二个缩进级别的列表项将大写 Alpha 用于项目标记。
图 17. "定义新多级列表"对话框
主文档部件的标记包含w:numPr 元素,该元素替代从抽象编号格式到样式的链接,这与创建编号格式时完全一样。
<w:p>
<w:pPr>
<w:pStyle w:val="Heading1"/>
</w:pPr>
<w:r>
<w:t>Paragraph One</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading2"/>
<w:numPr>
<w:ilvl w:val="1"/>
<w:numId w:val="3"/>
</w:numPr>
</w:pPr>
<w:r>
<w:t>Paragraph Two</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading3"/>
</w:pPr>
<w:r>
<w:t>Paragraph Three</w:t>
</w:r>
</w:p>
段落属性中的 w:numPr 元素替代抽象编号格式和标题 2 样式之间的链接。编号部件现在包含一个新的w:num 元素,用来定义 w:lvlOverride 元素。
<w:num w:numId="1">
<w:abstractNumId w:val="0"/>
</w:num>
<w:num w:numId="2">
<w:abstractNumId w:val="1"/>
</w:num>
<w:num w:numId="3">
<w:abstractNumId w:val="0"/>
<w:lvlOverride w:ilvl="0">
<w:lvl w:ilvl="0">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:pStyle w:val="Heading1"/>
<w:lvlText w:val="%1"/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="432"
w:hanging="432"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default"/>
</w:rPr>
</w:lvl>
</w:lvlOverride>
<w:lvlOverride w:ilvl="1">
<w:lvl w:ilvl="1">
<w:start w:val="1"/>
<w:numFmt w:val="upperLetter"/>
<w:pStyle w:val="Heading2"/>
<w:lvlText w:val="%1.%2"/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="576"
w:hanging="576"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default"/>
</w:rPr>
</w:lvl>
</w:lvlOverride>
. . .
两个 w:num 元素现在引用同一抽象编号格式。但是,第二个元素现在替代列表项格式。您可以看到级别 1 的级别替代现在指定 w:numFmt 元素的值为"upperLetter"。
处理 w:startOverride 元素
w:lvlOverride 元素可以包含一个子 w:startOverride 元素。
<w:num w:numId="2">
<w:abstractNumId w:val="2"/>
<w:lvlOverride w:ilvl="0">
<w:startOverride w:val="5"/>
</w:lvlOverride>
<w:lvlOverride w:ilvl="1">
<w:startOverride w:val="1"/>
</w:lvlOverride>
. . .
</w:num>
w:startOverride 元素可以使缩进级别的起始编号为指定的值。有时,当用户专门在用户界面中设置此值以强制继续从特定编号开始时,就需要这样做。这是标记构成可跳过编号列表中某个编号的文档的一种方式。
图 18. 跳过某个编号的编号列表
还有一种允许标记指定起始编号的方式。稍后会显示此标记。
定义列表样式
Word 中有一个选项允许您定义一个新的命名列表样式,然后在文档中的其他位置使用该样式。这是实现您自己的自定义编号格式的一种快速、简单的办法。为此,请选择要编号的文本,然后从多级列表选择"定义新列表样式"。
图 19. 定义新的列表样式
这将打开"定义新列表样式"对话框。
图 20. "定义新列表样式"对话框
完成此对话框后,选定段落将具有您指定的编号格式。然后,您也可以在文档中的其他位置应用这一样式。此功能影响标记。下面是您使用此模式时的间接寻址。
图 21. 列表样式的间接寻址
文档部件看上去与您应用其他形式的编号时一样。
<w:p>
<w:pPr>
<w:pStyle w:val="ListParagraph"/>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="2"/>
</w:numPr>
</w:pPr>
<w:r>
<w:t>1</w:t>
</w:r>
</w:p>
我们可以在编号部件中找到引用的 w:num 元素。
<w:num w:numId="2">
<w:abstractNumId w:val="0"/>
</w:num>
但如果我们看一下抽象编号元素,就会发现它看起来非常不同。它不包含子 w:lvl 元素,并使用 w:numStyleLink 元素来引用以前定义的样式。
<w:abstractNum w:abstractNumId="0">
<w:nsid w:val="03916EF0"/>
<w:multiLevelType w:val="multilevel"/>
<w:tmpl w:val="0409001D"/>
<w:numStyleLink w:val="EricsListStyle"/>
</w:abstractNum>
在样式部件中,您可以找到新定义的样式,该样式随后反过来引用编号部件中的 w:num 元素。
<w:style w:type="numbering"
w:customStyle="1"
w:styleId="EricsListStyle">
<w:name w:val="EricsListStyle"/>
<w:uiPriority w:val="99"/>
<w:rsid w:val="00B1427D"/>
<w:pPr>
<w:numPr>
<w:numId w:val="1"/>
</w:numPr>
</w:pPr>
</w:style>
编号部件中的 w:num 元素看起来如下所示。
<w:num w:numId="1">
<w:abstractNumId w:val="1"/>
</w:num>
它引用 w:abstractNum 元素,后者与往常一样包含级别格式。
<w:abstractNum w:abstractNumId="1">
<w:nsid w:val="2D235466"/>
<w:multiLevelType w:val="multilevel"/>
<w:tmpl w:val="0409001D"/>
<w:styleLink w:val="EricsListStyle"/>
<w:lvl w:ilvl="0">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:lvlText w:val="%1)"/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="360"
w:hanging="360"/>
</w:pPr>
</w:lvl>
<w:lvl w:ilvl="1">
<w:start w:val="1"/>
<w:numFmt w:val="lowerLetter"/>
<w:lvlText w:val="%2)"/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="720"
w:hanging="360"/>
</w:pPr>
</w:lvl>
. . .
列表项后缀的备选项
列表后缀是列表项与段落之间的空白内容。只有两个可能的值:制表符和空格。我们可以改变列表定义以使用空格而非制表符作为列表项后缀。
图 22. 使用空格而非制表符为后缀的列表
标记使用 w:suff 元素指定后缀。
<w:abstractNum w:abstractNumId="0">
<w:nsid w:val="21E167DA"/>
<w:multiLevelType w:val="multilevel"/>
<w:tmpl w:val="5BE82C98"/>
<w:lvl w:ilvl="0">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:pStyle w:val="Heading1"/>
<w:suff w:val="space"/>
<w:lvlText w:val="%1"/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="432"
w:hanging="432"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default"/>
</w:rPr>
</w:lvl>
处理 w:lvlRestart 元素
w:lvlRestart 元素允许标记控制某个特定级别何时重新开始计数。在以下示例中,当级别一中存在干预项目时,级别四列表项将开始重新计数:
图 23. 控制级别重新开始
上例中 w:lvl 元素(其中 w:ilvl 属性等于"3")的标记看起来如下所示。
<w:abstractNum w:abstractNumId="0">
<w:nsid w:val="065A6A4E"/>
<w:multiLevelType w:val="multilevel"/>
<w:tmpl w:val="06A2CF44"/>
<!-- several w:lvl elements elided -->
<w:lvl w:ilvl="3">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:lvlRestart w:val="1"/>
<w:lvlText w:val="%1.%2.%3.%4."/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="1728"
w:hanging="648"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default"/>
</w:rPr>
</w:lvl>
处理 w:isLgl 元素
w:isLgl 元素更改列表项的文本表示形式以便它将数字用于所有级别,而非将指定编号格式用于该级别,但这种情况仅出现在为给定缩进级别设置文本格式时。考虑以下文档,其中第三个缩进级别处的项目使用合法编号。
图 24. 级别三使用合法编号的列表
如果此列表没有对第三个缩进级别使用合法编号,它会显示为如下这样。
图 25. 未使用合法编号的列表
w:isLgl 元素的标记如下所示。
<w:abstractNum w:abstractNumId="0">
. . .
<w:lvl w:ilvl="2">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:pStyle w:val="Heading3"/>
<w:isLgl/>
<w:lvlText w:val="%1.%2.%3)"/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="720"
w:hanging="720"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default"/>
</w:rPr>
</w:lvl>
组合列表项文本的算法
若要组合列表项文本,您必须确定:
段落的 w:lvl 格式。
段落的缩进级别。
段落的每个父缩进级别的编号。例如,如果段落位于第四个缩进级别,则必须确定与该段落关联的第一、第二、第三和第四级的级别号。
拥有这三项后,组合列表项文本只不过是一个简单的设置文本格式的操作。
段落可能包含具有 w:ilvl 和 w:numId 元素的编号属性。
<w:p>
<w:pPr>
<w:pStyle w:val="ListParagraph"/>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="1"/>
</w:numPr>
</w:pPr>
<w:r>
<w:t>Paragraph one.</w:t>
</w:r>
</w:p>
在此示例中,使用为缩进级别指定的 w:ilvl。转到编号部件,查找 w:num 元素。如果存在包含 w:lvl 元素的 w:lvlOverride 元素,则 w:lvl 元素适用。如果没有 w:lvlOverride 元素,或者 w:lvlOverride 元素不包含缩进级别的w:lvl 元素,则查找关联 w:abstractNum 元素,并使用在 w:abstractNum 中指定的 w:lvl 格式。如果 w:num 元素包含 w:lvlOverride 元素,使用在替代中为缩进级别指定的 w:lvl 元素。
如果段落不包含 w:numPr 复杂元素,并且段落样式包含 w:numPr 元素,则存在一个引用该样式的抽象编号元素。使用引用该样式的 w:lvl。这同样会提供缩进级别。
确定 w:lvl 格式元素和缩进级别后,您可以确定每个级别的列表编号。必须统计同一级别中当前段落之前的段落,同时注意 w:lvlRestart 元素和 w:start 元素。这里最适合函数编程。您可以构建一个无状态表达式来计算每个缩进级别的项目数。这可能不是完成此任务的最有效方式。它可能比另一种方法使用更多的 CPU 处理,但却很容易调试,并且对大多数应用场景而言,它可能足够快。我在我的速度最慢计算机上做过非正式测试,它仍然能够几乎在瞬间完成。
具有适当的 w:lvl 元素和每个缩进级别的项目编号列表后,创建列表项文本只不过是一个简单的文本组合过程而已。
结论
Open XML WordprocessingML 中的编号很复杂,这也是理所当然的。在准确提取文档文本时,理解编号非常重要。此外,生成使用编号标记的文档是文档组合解决方案中的一种有效方法。
其他资源
要开始使用 Open XML,请参阅 MSDN 上的 Open XML Developer Center(该链接可能指向英文页面)。那儿提供有大量内容,包括文章、操作方法视频和指向众多博客的链接。特别地,下面的链接提供重要信息,有助您开始使用 Open XML SDK 2.0: