Xport: XHTML 解析和报告工具包






4.73/5 (10投票s)
用于生成和解析 xhtml 文档的开源 C++ 类模板库。
引言
Xport,XHTML parsing & objective reporting toolkit(XHTML 解析和客观报告工具包),是一个 C++ 模板类库,可以包含在任何 C++ 项目中,用于创建和生成 xhtml 文档。尽管 Xport 的开发初衷是为了创建用于报告目的的 xhtml 文档,但 Xport 也可以用于创建许多其他用途的 xhtml 文档。
Xport 还提供了 xhtml 和样式表解析功能。Xport 可以解析几乎任何 xhtml 文档,以及格式不太差的 HTML 文档。
Xport 提供了生成和解析各种文档类型的能力。Xport 提供了三种文档类型类:xhtml strict 1.0、xhtml transitional 1.0 和 xhtml frameset 1.0。Xport 的灵活设计还允许轻松包含其他文档类型。无论您使用哪种文档类型,Xport 都会强制执行该特定文档类型的规则。
Xport 还提供了使用标准字符类型或宽字符类型来支持 Unicode 的能力。
Xport 中提供了多种迭代器,可在处理文档、元素和样式表时提供类似 STL 的功能。这些迭代器与 STL 容器和算法兼容。还提供了一个后代迭代器,用于遍历文档树或文档中的子树。使用 STL 的算法,可以快速轻松地找到文档树中任何可识别的元素。
Xport 包含一个设计良好的类层次结构和一个丰富且文档齐全的接口。关键类的命名恰当,以传达其用途。类型名称,如 document
、element
、markup
、comment
、stylesheet
和 stylesheet_rule
,使得使用这些类直观易懂。尽管 Xport 完全由类模板组成,但使用 Xport 时无需使用模板语法,因为所有各种类模板和文档类型都提供了类型别名。Xport 中关键类的许多操作都反映了 STL 容器中的操作,提供了直观且友好的接口。
从上面的链接中可用的文档详细介绍了每个类的每个操作,并为 Xport 所有类的每个公共操作提供了示例。
使用代码
尽管 Xport 完全由类模板组成,但您无需了解模板知识即可使用 Xport 及其所有功能。Xport 中提供了类型别名,允许在不直接处理模板类的情况下使用它。例如,以下代码片段创建并保存了一个基本的 xhtml strict 文档。
// bring namespace into current scope using namespace Xport; // create an xhtml document with the root elements // (<html>, <head>, and <body>) document doc(root_doc); // insert a paragraph element into the document's // body element, returning an iterator markup::iterator it = doc.body()->insert(element(p)); it->insert("This is the first paragraph of the document"); // insert a paragraph into the document using the // insertion operator *doc.body() << (element(p) << "This is the second paragraph of the document"); // write the document doc.write("c:/myDoc.htm");
使用 Xport 的样式表类,创建样式表也同样容易。下面的示例演示了如何创建带有链接样式表的简单 xhtml 文档。
// the following include gives access to all Xport's interface #include "xhtml_doc.h" using namespace Xport; // create a root document called 'doc' document doc(root_doc); // insert a title in the head element *doc.title() << "Sample xhtml document"; // insert a heading into the documents body *doc.body() << (element(h1) << "This is a sample xhtml document!"); // insert paragraph markup::iterator it = doc.body()->insert(element(p)); *it << "This document was created by Xport, " << "to demonstrate it's xhtml generation features. " << "pcdata can be inserted into elements all at once, " << "or seperately. The push_back() operation behaves " << "similar to the insert() operation when insert() " << "is supplied a single argument. When supplied a " << "single argument (the pcdata to insert), " << "the insert() operation inserts the object/pcdata " << "at the end of the called element. " << "But when supplied with an additional argument, " << "a child iterator, the child iterator " << "specifies where the object/pcdata will be inserted."; // insert user list it = doc.body()->push_back(element(ul)); *it << (element(li, "li1") << "List item 1"); *it << (element(li, "", "red") << "List item 2"); *it << (element(li, "", "red") << "List item 3"); // create stylesheet object stylesheet ss; // add rule for heading stylesheet::iterator sit = ss.insert(stylesheet_rule("h1")); *sit << declaration(css::color, "red") << declaration(text_align, "center"); // add rule for paragraph sit = ss.insert(stylesheet_rule("p")); *sit << declaration(margin_left, "30px") << declaration(padding, "10px") << declaration(css::width, "400px") << declaration(css::border, "thin groove blue"); // add rule for user list sit = ss.insert(stylesheet_rule("ul")); *sit << declaration(padding_left, "20px"); // add rule for element id li1 sit = ss.insert(stylesheet_rule("#li1")); *sit << declaration(css::color, "green"); // add rule for class selector red sit = ss.insert(stylesheet_rule("li.red")); *sit << declaration(css::color, "red"); // add stylesheet link to document header it = doc.head()->insert(element(Xport::link)); it->attribute(rel, "stylesheet"); it->attribute(type, "text/css"); it->attribute(href, "test_doc.css"); // write the document object to a file formatter fmtr("c:/test_doc.htm"); fmtr.option(max_line_length, 80); doc.write(fmtr); // write the stylesheet object to a file ss.write("c:/test_doc.css");
以下类构成了 Xport 的接口
xhtml 类
Xport 的 xhtml 类支持创建和解析 xhtml 文档的功能。如上所述,Xport 完全由类模板组成,但为方便用户使用,为所有接口类声明了类型别名。xhtml 模板类被参数化为两种类型:文档类型 和 字符类型。下表列出了 Xport 的所有 xhtml 接口类模板以及这些类可用的类型别名。
类模板 | 类型别名 | |||||
---|---|---|---|---|---|---|
xhtml strict |
wchar xhtml strict |
xhtml transitional |
wchar xhtml transitional |
xhtml frameset |
wchar xhtml frameset |
|
xhtml_doc | 文档 | wdocument | tdocument | wtdocument | fdocument | wfdocument |
xhtml_markup | markup | wmarkup | tmarkup | wtmarkup | fmarkup | wfmarkup |
xhtml_element | element | welement | telement | wtelement | felement | wfelement |
xhtml_pcdata | pcdata | wpcdata | tpcdata | wtpcdata | fpcdata | wfpcdata |
xhtml_comment | comment | wcomment | tcomment | wtcomment | fcomment | wfcomment |
xhtml_processing_instruction | procinstr | wprocinstr | tprocinstr | wtprocinstr | fprocinstr | wfprocinstr |
xhtml_formatter | formatter | wformatter | tformatter | wtformatter | fformatter | wfformatter |
xhtml_parser | parser | wparser | tparser | wtparser | fparser | wfparser |
表 1:Xport 的 xhtml 类模板和类型别名
Xport 的默认文档类型是 xhtml strict,在上面的表中以蓝色显示。大多数示例报告将反映此文档类型。因此,库的用户通常只会使用上面蓝色显示的类型别名来创建文档。
下面简要描述了 Xport 的 xhtml 类型。将使用默认类型别名来描述可用的不同 xhtml 类型。
文档
在 Xport 中,文档 类型封装了一个 xhtml 文档。document
对象是您将使用的最重要的对象之一。document
对象以树结构或文档树 的形式组织其内容。标准 xhtml 文档通常包含 html
、head
、title
和 body
元素。在 Xport 中,这些元素被称为根元素,包含这些根元素的 document
被认为是根文档。创建 document
对象时,您可以选择将其创建为根文档,并包含这些根元素。这些根元素以及其中包含的所有其他元素构成了文档树。一旦将内容添加到 document
中,就可以将 document
写入文件或流。document
对象还可以解析 xhtml 文件以及 html 文件。解析 html 文件的结果将因 html 文件的形式而异。
markup
markup
是 element
、comment
和 procinstr
的基类型。markup
主要用于 Xport 的标记迭代器,下面将进一步讨论它们。所有标记迭代器都返回 markup
对象的引用和指针,这些对象实际上是从 markup
派生的对象。因此,markup
的接口确实非常重要,因为只有通过 markup
的接口,我们在使用标记迭代器时才能访问从 markup
派生的那些对象。
element
Xport 的 element
类型封装了一个 xhtml 元素。在创建文档内容时,element
对象比任何其他对象类型使用得都更频繁。element
对象是唯一可以包含其他 markup
对象的 markup
对象,这使得 element
对象承担了构成文档树的责任。有多种方法可以将其他 markup
对象添加或插入到 element
对象中,这些方法都已在文档和示例中进行了详细介绍。Xport 只允许将元素插入到不违反所用文档类型规格的元素中。例如,Xport 不允许将 p
元素插入到另一个 p
元素中,因为这对于所有文档类型来说都违反 xhtml。每种文档类型都有特定的规则,或文档类型定义,Xport 会强制执行这些规则。
element
在其构造函数中接受三个参数。第一个参数是必需的,用于指定要创建的元素的标签名。在 Xport 中,为了方便起见,标签名被枚举了。第二个可选参数用于指定元素的id 属性,第三个可选参数用于指定元素的class 属性。
element
还可以被赋予属性,这些属性也为了方便起见进行了枚举。文档类型定义指定了哪些属性可以分配给哪些元素,Xport 也会强制执行这些规则。Xport 还提供了一种简单的方法来为特定元素分配样式,通过样式属性,但由于 Xport 支持样式表,因此鼓励使用样式表而不是样式属性。
pcdata
Xport 的 pcdata
类型封装了 xhtml 文档中的 PCDATA(可解析字符数据)。pcdata
对象在 Xport 中主要被隐式使用。每当将文本插入到元素中时,Xport 就会将文本放入一个 pcdata
对象中。当一个 element
包含 PCDATA 时,该 element
将包含一个或多个 pcdata
对象,这些对象包含 PCDATA。构成元素内 PCDATA 的 pcdata
对象的数量取决于 PCDATA 插入到 element
中的方式。
无论元素是表示为 element
对象还是 pcdata
对象的一部分,当 Xport 解析 (x)html 文档时,parser
始终会将元素(包括内联元素)解析为 element
对象,而不是将它们包含在 pcdata
对象中。这意味着,例如,如果一个段落元素包含包含内联元素和 PCDATA 的内容,该段落元素将被解析为多个独立的 pcdata
对象和 element
对象。
comment
Xport 的 comment
是一个非常简单的类型,封装了一个 xhtml 注释。注释在 xhtml 中不是必需的,但它们对于记录 xhtml 源非常有用。与 element
一样,comment
也派生自 markup
,并且也被视为 markup
对象。
procinstr
Xport 的 procinstr
封装了一个 xhtml 处理指令。Xhtml 中有许多形式的处理指令,但所有处理指令都用 **<?** 和 **?>** 分隔。最常见的处理指令类型之一是 PHP 处理指令。procinstr
也派生自 markup
,并且也被视为 markup
对象。
formatter
Xport 的 formatter
用于格式化文档的输出,无论是输出到文件还是流。formatter
对象提供了对 xhtml 输出的详细控制。使用 formatter
,您可以指定文档中任何元素的布局样式。您还可以指定最大行长度以及文档中实体的呈现方式。事实上,借助 Xport 的 parser
和 Xport 的 formatter
,您可以使用该工具包来简单地按照您的喜好重新格式化现有的 xhtml 文档。
parser
Xport 的 parser
允许解析 xhtml 和 html 文档。如果 xhtml 格式正确,parser
对象将毫无问题地解析该文档。如果文档格式不正确,parser
对象将尽力解析该文档并处理其错误。parser
对象会将文件或流解析为 Xport document
对象。无论要解析的文档有多差,生成的 document
对象将始终是格式良好的,因为 Xport 不允许无效的 xhtml。parser
对象还允许用户指定文档解析方式的选项,使用户能够控制换行符保留、实体转换和字节顺序标记保留等内容。parser
对象可以根据需要生成其进度日志。
样式表类
Xport 的样式表功能通过另一组模板类实现,这些类仅由字符类型进行参数化。与 xhtml 模板类一样,为样式表模板类声明了类型别名,以使其更容易使用。下表说明了样式表模板类及其类型别名。
类模板 | 类型别名 | |
---|---|---|
窄字符 | 宽字符 | |
xhtml_stylesheet | stylesheet | wstylesheet |
xhtml_stylesheet_rule | stylesheet_rule | wstylesheet_rule |
xhtml_stylesheet_import | stylesheet_import | wstylesheet_import |
xhtml_stylesheet_comment | stylesheet_comment | wstylesheet_comment |
stylesheet_declaration | declaration | wdeclaration |
表 2:Xport 的样式表类模板和类型别名
Xport 的样式表类型别名的默认字符类型是标准窄字符类型。使用标准窄字符,库用户将只使用表中左侧以蓝色显示的类型别名。Xport 的 stylesheet
对象封装了一个级联样式表。stylesheet
对象可以轻松地写入文件,或嵌入到文档中。Xport 的 stylesheet
对象还可以解析现有样式表,从文件或流中解析。
下面简要描述了 Xport 的样式表类型。将使用默认类型别名来描述可用的不同样式表类型。
stylesheet
Xport 的 stylesheet
封装了一个级联样式表。stylesheet
的接口很小,但非常重要。它的三个操作 add_item()
、write()
和 parse()
赋予了 stylesheet
主要功能。有三种类型的对象可以添加到 stylesheet
对象中:stylesheet_rule
、stylesheet_comment
和 stylesheet_import
。这使得 stylesheet
对象比 document
对象更简单。将样式表添加到文档的大部分工作涉及下面详细介绍的 stylesheet_rule
。
stylesheet_rule
Xport 的 stylesheet_rule
封装了一个 CSS 规则。在 Xport 中创建样式表时,stylesheet_rule
对象比任何其他样式表类型使用得都多。由于样式表规则总是包含一个选择器,该选择器指定了规则适用的文档部分,因此 stylesheet_rule
在其构造函数中接受一个必需的字符串参数,该参数指定了规则的选择器。创建 stylesheet_rule
对象后,通过 add_declaration()
操作向其添加声明。这是 stylesheet_rule
中的主要操作,并且有两种形式。第一种形式接受一个 declaration
对象,该对象将在下面介绍。第二种形式的操作接受两个参数。第一个参数指定 css property
(属性),第二个参数指定该属性的value(值)。css 属性名称为了方便起见被枚举了。属性值被指定为字符串参数。
stylesheet_import
Xport 的 stylesheet_import
有一个基本目的,即允许将另一个样式表导入到当前样式表中。
stylesheet_comment
Xport 的 stylesheet_comment
封装了一个样式表注释。此类型允许用户向样式表中添加注释。
declaration
Xport 的 declaration
封装了一个 CSS 声明。一旦创建了 declaration
对象,就可以将其添加到 stylesheet_rule
中。declaration
在其构造函数中期望两个必需的参数。第一个参数指定 css property
(属性),第二个参数指定该属性的value(值)。
迭代器类
Xport 的迭代器功能可用于 xhtml 标记和样式表。标记有两种类型的迭代器:子标记迭代器和后标记迭代器。顾名思义,子迭代器遍历元素或文档的直接子级,而后迭代器遍历所有后代。
下面简要描述了 Xport 的迭代器类型。
markup::iterator 和 markup::const_iterator
Xport 的子标记迭代器 iterator
和 const_iterator
对于创建和解析 xhtml 文档都非常有用。这些迭代器不仅允许遍历子标记对象,还可以用于插入、添加和删除子标记对象。特别是 iterator
非常有用,它从元素的 insert()
操作中返回。返回的 iterator
进而可以用于在 iterator
指向的元素中插入其他标记。鼓励用户在文档中生成内容时大量使用 iterator
。
markup::descendant_iterator 和 markup::const_descendant_iterator
当需要遍历文档或文档中特定元素的后代时,使用 Xport 的后标记迭代器 descendant_iterator
和 const_descendant_iterator
。这些迭代器以预序方式遍历。文档对象的后代迭代器可以遍历整个文档中的每个标记对象,这可能非常方便。与 iterators
一样,后代迭代器也可以用于在文档中插入、添加和删除标记。
stylesheet::iterator 和 stylesheet::const_iterator
Xport 的样式表迭代器 iterator
和 const_iterator
对于创建和解析样式表都非常有用。这些迭代器不仅允许遍历样式表项,还可以用于插入、添加和删除样式表项,包括样式表规则、导入规则和注释。特别是 iterator
非常有用,它从样式表 insert()
操作中返回。插入样式表规则时,返回的 iterator
进而可以用于在 iterator
指向的 stylesheet_rule
中插入声明。鼓励用户在样式表中生成样式表项时大量使用 iterator
。
stylesheet_item::iterator 和 stylesheet_item::const_iterator
Xport 的样式表规则迭代器 iterator
和 const_iterator
对于创建和解析样式表规则都非常有用。虽然这些迭代器遍历嵌入在 stylesheet_rule 对象中的声明,但此迭代器在 stylesheet_rule 的基类 stylesheet_item 中声明和定义。
历史
版本 1.6.1
引入到 CodeProject
版本 1.6.5
修复了由与 windows 定义的“small”名称冲突引起的编译器错误。
为 stylesheet_iterator 和 stylesheet_rule_iterator 添加了 operator < 操作。
杂项小错误修复。
版本 1.6.7
修复了 document::insert(stylesheet) 中的错误;
修复了 stylesheet_rule_iterator 中的 const 问题。
删除了未使用的 clear_all 枚举。
VC6 兼容性更改。
有关 Xport 的更多信息以及完整的版本历史记录,请访问 Xport 的主页