基于C/C++的rapidxml加载xml大文件 - 上部分翻译

RAPIDXML手册

版本 1.13

版权所有 (C) 2006, 2009 Marcin Kalicinski
有关许可证信息,请参阅随附的文件许可证 .txt。


目录

1. 什么是 RapidXml?
1.1 依赖性和兼容性
1.2 字符类型和编码
1.3 错误处理
1.4 内存分配
1.5 W3C 合规性
1.6 API 设计
1.7 可靠性
1.8 致谢
2.两分钟教程
2.1 解析
2.2 访问 DOM 树 2.3 修改 DOM 树

2.4 打印 XML
3.与常规 XML 解析器
的区别 3.1 源文本
的生存期 3.2 字符串
的所有权 3.3 破坏性与非破坏性模式
4.性能
4.1 与其他解析器
的比较 5.参考
 

1. 什么是 RapidXml?

RapidXml 试图创建最快的 XML DOM 解析器,同时保留可用性、可移植性和合理的 W3C 兼容性。它是一个用 C++ 编写的原位解析器,解析速度接近在相同数据上执行的 strlen() 函数。

整个解析器包含在单个头文件中,因此不需要构建或链接。要使用它,您只需要将 rapidxml.hpp 文件复制到一个方便的地方(例如您的项目目录),并将其包含在需要的地方。您可能还希望使用标头 rapidxml_print.hpp 中包含的打印功能。

1.1 依赖关系和兼容性

RapidXml 除了标准C++库(<cassert>、<cstdlib>、<new> 和 <exception>,除非禁用异常)之外,没有其他依赖项。它应该在任何合理兼容的编译器上编译,并在 Visual C++ 2003、Visual C++ 2005、Visual C++ 2008、gcc 3、gcc 4 和 Comeau 4.3.3 上进行了测试。请注意,即使启用了最高警告级别,也不会在这些编译器上生成警告。

1.2 字符类型和编码

RapidXml 与字符类型无关,可以处理窄字符和宽字符。当前版本不完全支持 UTF-16 或 UTF-32,因此使用宽字符在某种程度上是无能为力的。但是,如果数据的字节序与计算机的字节序匹配,则它应该成功解析包含 UTF-16 或 UTF-32 wchar_t字符串。完全支持 UTF-8,包括所有数字字符引用,这些引用被扩展为适当的 UTF-8 字节序列(除非启用parse_no_utf8标志)。

请注意,RapidXml 不执行解码 - name() 和 value() 函数返回的字符串将包含使用与源文件相同的编码编码的文本。Rapidxml理解并扩展了以下字符引用: ' & “ < > &#...;其他字符引用不会展开。

1.3 错误处理

默认情况下,RapidXml 使用 C++ 异常来报告错误。如果不希望出现此行为,则可以定义RAPIDXML_NO_EXCEPTIONS来抑制异常代码。有关更多信息,请参见 parse_error 类和 parse_error_handler() 函数。

1.4 内存分配

RapidXml 使用一个特殊的内存池对象来分配节点和属性,因为使用 new 运算符直接分配太慢了。可以使用 memory_pool::set_allocator() 函数自定义池执行的基础内存分配。有关详细信息,请参阅第 memory_pool 类。

1.5 W3C 合规性

RapidXml 不是符合 W3C 的解析器,主要是因为它忽略了 DOCTYPE 声明。还有许多其他轻微的不兼容问题。尽管如此,它仍然可以成功地解析和生成 W3C 一致性套件中所有有效 XML 文件的完整树(超过 1000 个专门设计用于查找 XML 处理器缺陷的文件)。在破坏性模式下,它对一小组内置实体执行空格规范化和字符实体替换。

1.6 API设计

RapidXml API 是简约的,以尽可能减小代码大小,并便于在嵌入式环境中使用。其他便利功能在单独的标头中提供:rapidxml_utils.hpp 和 rapidxml_print.hpp。这些标头的内容不是库的重要组成部分,并且当前未记录(代码中的注释除外)。

1.7 可靠性

RapidXml 非常健壮,并附带了大量的单元测试。我们特别注意确保解析器的稳定性,无论向它抛出什么源文本。其中一个单元测试生成 100,000 个随机损坏的 XML 文档变体,这些变体(未损坏时)包含 RapidXml 识别的所有构造。当 RapidXml 正确识别出已引入错误,并且不会崩溃或无限循环时,它就通过了此测试。

另一个单元测试将 RapidXml 与另一个结构良好的 XML 解析器进行正面交锋,并验证它们的输出是否在各种小型和大型文档中匹配。

另一个测试向 RapidXml 提供来自 W1000C 合规性套件的 3 多个测试文件,并验证是否获得了正确的结果。还有一些其他测试可以单独验证每个 API 函数,并测试各种解析模式是否按预期工作。

1.8 致谢

我要感谢 Arseny Kapoulkine 在 pugixml 上所做的工作,这是这个项目的灵感来源。还要感谢 Kristen Wegner 创建了 pugxml,pugixml 就是从中衍生出来的。Janusz Wohlfeil 友好地在我无权访问的硬件上运行了 RapidXml 速度测试,使我能够扩展性能比较表。

2. 两分钟教程

2.1 解析

以下代码使 RapidXml 解析名为 : object 的以零结尾的字符串现在是包含已解析 XML 表示形式的 DOM 树的根。由于所有 RapidXml 接口都包含在 namespace 中,因此用户必须将此命名空间的内容带入范围,或者完全限定所有名称。类 xml_document 表示 DOM 层次结构的根。通过公有继承,也是xml_node和memory_pool。xml_document::p arse() 函数的模板参数用于指定解析标志,您可以使用这些标志微调解析器的行为。请注意,标志必须是编译时常量。text

using namespace rapidxml;
xml_document<> doc;    // character type defaults to char
doc.parse<0>(text);    // 0 means default parse flags

docrapidxml

2.2 访问 DOM 树

要访问 DOM 树,请使用 xml_node 和 xml_attribute 类的方法:

cout << "Name of my first node is: " << doc.first_node()->name() << "\n";
xml_node<> *node = doc.first_node("foobar");
cout << "Node foobar has value " << node->value() << "\n";
for (xml_attribute<> *attr = node->first_attribute();
     attr; attr = attr->next_attribute())
{
    cout << "Node foobar has attribute " << attr->name() << " ";
    cout << "with value " << attr->value() << "\n";
}

2.3 修改 DOM 树

解析器生成的 DOM 树是完全可修改的。可以添加/删除节点和属性,并更改其内容。下面的示例创建一个 HTML 文档,其唯一内容是指向 google.com 网站的链接: 一个怪癖是节点和属性不拥有其名称和值的文本。这是因为通常它们只存储指向源文本的指针。因此,在为节点分配新名称或值时,必须注意确保字符串的正确生存期。实现此目的的最简单方法是从 xml_document 内存池中分配字符串。在上面的示例中,这不是必需的,因为我们只分配字符常量。但是下面的代码使用 memory_pool::allocate_string() 函数来分配节点名称(该名称将与文档具有相同的生存期),并将其分配给一个新节点: 查看参考部分,了解整个接口的描述。

xml_document<> doc;
xml_node<> *node = doc.allocate_node(node_element, "a", "Google");
doc.append_node(node);
xml_attribute<> *attr = doc.allocate_attribute("href", "google.com");
node->append_attribute(attr);
xml_document<> doc;
char *node_name = doc.allocate_string(name);        // Allocate string and copy name into it
xml_node<> *node = doc.allocate_node(node_element, node_name);  // Set node name to node_name

2.4 打印XML

您可以将 AND 对象打印成 XML 字符串。使用 header() 中定义的 print() 函数或运算符<<。xml_documentxml_noderapidxml_print.hpp

using namespace rapidxml;
xml_document<> doc;    // character type defaults to char
// ... some code to fill the document

// Print to stream using operator <<
std::cout << doc;   

// Print to stream using print function, specifying printing flags
print(std::cout, doc, 0);   // 0 means default printing flags

// Print to string using output iterator
std::string s;
print(std::back_inserter(s), doc, 0);

// Print to memory buffer using output iterator
char buffer[4096];                      // You are responsible for making the buffer large enough!
char *end = print(buffer, doc, 0);      // end contains pointer to character after last printed character
*end = 0;                               // Add string terminator after XML

3. 与常规 XML 解析器的区别

RapidXml 是一个原位解析器,这使得它能够实现非常高的解析速度。In-situ 意味着解析器不会复制字符串。相反,它会在 DOM 层次结构中放置指向源文本的指针。

3.1 源文本的生存期

原位分析要求源文本的生存时间至少与文档对象一样长。如果源文本被销毁,DOM 树中节点的名称和值也会被销毁。此外,空格处理、字符实体转换和字符串的零终止要求在解析期间修改源文本(但请参阅非破坏性模式)。这使得文本在被 RapidXml 解析后就无法进行进一步处理。

然而,在许多情况下,这些都不是严重的问题。

3.2 字符串的所有权

RapidXml 生成的节点和属性不拥有其名称和值字符串。他们只是拿着指向他们的指针。这意味着在使用 xml_base::name(const Ch *) 或 xml_base::value(const Ch *) 函数手动设置这些值时必须小心。必须注意确保传递的字符串的生存期至少与节点/属性的生存期一样长。实现它的最简单方法是从文档拥有的memory_pool中分配字符串。为此,请使用 memory_pool::allocate_string() 函数。

3.3 破坏性与非破坏性模式

默认情况下,解析器在解析过程中修改源文本。这是实现字符串的字符实体转换、空格规范化和零终止所必需的。

在某些情况下,这种行为可能是不可取的,例如,如果源文本驻留在只读内存中,或者直接从文件映射到内存。通过使用适当的分析器标志 (parse_non_destructive),可以禁用源文本修改。但是,由于 RapidXml 是原位解析的,因此它显然具有以下副作用:

  • 未进行空格规范化
  • 未进行实体引用转换
  • 名称和值不是以零结尾的,您必须使用 xml_base::name_size() 和 xml_base::value_size() 函数来判断它们的结束位置

4. 性能

RapidXml 通过使用以下几种技术来实现其速度:

  • 原位解析。在构建 DOM 树时,RapidXml 不会复制字符串数据,例如节点名称和值。相反,它存储指向源文本内部的指针。
  • 使用模板元编程技术。这允许它将大部分工作转移到编译时间。通过模板的魔力,C++ 编译器为您使用的解析器标志的任意组合生成单独的解析代码副本。在每个副本中,所有可能的决策都是在编译时做出的,所有未使用的代码都被省略了。
  • 广泛使用查找表进行解析。
  • 手动调整的 C++,在几个最流行的 CPU 上完成分析。

这导致了一个非常小而快速的代码:一个解析器,它是根据每次调用的确切需求定制的。

4.1 与其他解析器的比较

下表将 RapidXml 的速度与其他一些解析器以及对相同数据执行的 strlen() 函数进行了比较。在现代 CPU(截至 2007 年)上,您可以预期解析吞吐量接近 1 GB/s。根据经验,解析速度比 Xerces DOM 快 50-100 倍,比 TinyXML 快 30-60 倍,比 pugxml 快 3-12 倍,比 pugixml 快 5% - 30%,pugixml 是我所知道的最快的 XML 解析器。

  • 测试文件是一个真实世界的 50kB 大小、中等密度的 XML 文件。
  • 所有计时都是通过使用奔腾兼容 CPU 中的 RDTSC 指令完成的。
  • 不使用按配置文件优化。
  • 所有解析器都以最快的模式运行。
  • 结果以每个字符的 CPU 周期数给出,因此 CPU 的频率无关紧要。
  • 结果是大量运行的最小值,以最大程度地减少操作系统活动、任务切换、中断处理等的影响。
  • 测试文件的单次解析大约需要 1/10 毫秒,因此在大量运行时,很有可能达到至少一次无中断连续状态,并获得不受干扰的结果。

平台

编译器

strlen()RapidXml的普吉XML 0.3pugxml的TinyXml的

奔腾 4

MSVC 8.0

2.5

5.4

7.0

61.7

298.8

奔腾 4

GCC 4.1.1

0.8

6.1

9.5

67.0

413.2

核心 2

MSVC 8.0

1.0

4.5

5.0

24.6

154.8

核心 2

GCC 4.1.1

0.6

4.6

5.4

28.3

229.3

Athlon XP系列

MSVC 8.0

3.1

7.7

8.0

25.5

182.6

Athlon XP系列

GCC 4.1.1

0.9

8.2

9.2

33.7

265.2

奔腾 3

MSVC 8.0

2.0

6.3

7.0

30.9

211.9

奔腾 3

GCC 4.1.1

1.0

6.7

8.9

35.3

316.0

(*)所有结果均以源文本每个字符的 CPU 周期为单位


类 模板 RapidXML::memory_pool

在 rapidxml.hpp
中定义 xml_document 的基类

描述

解析器使用此类来创建新的节点和属性,而不会产生动态内存分配的开销。在大多数情况下,您不需要直接使用此类。但是,如果您需要手动创建节点或修改节点的名称/值,建议您使用相关xml_document memory_pool来分配内存。这不仅比使用运算符分配它们更快,而且它们的生存期将与文档的生存期相关联,这可能只是内存管理。

调用 allocate_node() 或 allocate_attribute() 函数以从池中获取新节点或属性。您还可以调用 allocate_string() 函数来分配字符串。然后,可以将此类字符串用作节点的名称或值,而无需担心其生存期。请注意,没有 free() 函数 -- 当调用 clear() 函数或销毁池时,所有分配都会立即释放。

也可以创建一个独立的memory_pool,并使用它来分配节点,其生存期不会与任何文档绑定。

池维护 RAPIDXML_STATIC_POOL_SIZE 字节的静态分配内存。在静态内存耗尽之前,不会进行动态内存分配。当静态内存耗尽时,pool 会使用全局 new[] 和 delete[] 运算符分配大小为 RAPIDXML_DYNAMIC_POOL_SIZE 的其他内存块。可以通过设置自定义分配例程来更改此行为。使用 set_allocator() 函数来设置它们。

节点、属性和字符串的分配以 RAPIDXML_ALIGNMENT 字节对齐。此值默认为目标体系结构上指针的大小。

为了从解析器获得绝对最佳性能,重要的是从单个连续的内存块分配所有节点。否则,在两个(或多个)不相交的内存块之间跳转时,缓存未命中会大大减慢解析速度。如果需要,您可以调整RAPIDXML_STATIC_POOL_SIZERAPIDXML_DYNAMIC_POOL_SIZERAPIDXML_ALIGNMENT,以获得最佳的内存浪费,从而降低性能。为此,请在包含 rapidxml.hpp 文件之前定义它们的值。

参数

中文

已创建节点的字符类型。

构造 函数 memory_pool::memory_pool

概要

memory_pool();

描述

使用默认分配器函数构造空池。

破坏者 memory_pool::~memory_pool

概要

~memory_pool();

描述

销毁池并释放所有内存。这会导致释放池分配的节点占用的内存。从池中分配的节点不再有效。

函数 memory_pool::allocate_node

概要

xml_node<Ch>* allocate_node(node_type type, const Ch *name=0, const Ch *value=0, std::size_t name_size=0, std::size_t value_size=0);

描述

从池中分配一个新节点,并选择性地为其分配名称和值。如果无法容纳分配请求,此函数将抛出 std::bad_alloc。如果通过定义 RAPIDXML_NO_EXCEPTIONS 禁用异常,此函数将调用 rapidxml::p arse_error_handler() 函数。

参数

类型

要创建的节点的类型。

名字

要分配给节点的名称,或 0 表示不指定任何名称。

价值

要分配给节点的值,或 0 表示不分配任何值。

name_size

要分配的名称的大小,或 0 根据名称字符串自动计算大小。

value_size

要分配的值的大小,或 0 根据值字符串自动计算大小。

返回

指向已分配节点的指针。此指针永远不会为 NULL。

函数 memory_pool::allocate_attribute

概要

xml_attribute<Ch>* allocate_attribute(const Ch *name=0, const Ch *value=0, std::size_t name_size=0, std::size_t value_size=0);

描述

从池中分配一个新属性,并选择性地为其分配名称和值。如果无法容纳分配请求,此函数将抛出 std::bad_alloc。如果通过定义 RAPIDXML_NO_EXCEPTIONS 禁用异常,此函数将调用 rapidxml::p arse_error_handler() 函数。

参数

名字

要分配给属性的名称,或 0 表示不指定名称。

价值

要分配给属性的值,或 0 表示不指定任何值。

name_size

要分配的名称的大小,或 0 根据名称字符串自动计算大小。

value_size

要分配的值的大小,或 0 根据值字符串自动计算大小。

返回

指向已分配属性的指针。此指针永远不会为 NULL。

函数 memory_pool::allocate_string

概要

Ch* allocate_string(const Ch *source=0, std::size_t size=0);

描述

从池中分配给定大小的 char 数组,并选择性地将给定的字符串复制到该数组中。如果无法容纳分配请求,此函数将抛出 std::bad_alloc。如果通过定义 RAPIDXML_NO_EXCEPTIONS 禁用异常,此函数将调用 rapidxml::p arse_error_handler() 函数。

参数

String 用于初始化分配的内存,或 0 表示不初始化它。

大小

要分配的字符数,或从源字符串长度自动计算的字符数为零;如果 size 为 0,则必须指定源字符串并以 null 结尾。

返回

指向已分配的 char 数组的指针。此指针永远不会为 NULL。

函数 memory_pool::clone_node

概要

xml_node<Ch>* clone_node(const xml_node< Ch > *source, xml_node< Ch > *result=0);

描述

克隆xml_node及其子节点和属性的层次结构。节点和属性是从此内存池中分配的。名称和值不会被克隆,而是在克隆和源之间共享。可以选择将结果节点指定为第二个参数,在这种情况下,其内容将替换为克隆的源节点。当您想要克隆整个文档时,这很有用。

参数

要克隆的节点。

结果

用于放置结果的节点,或 0 用于自动分配结果的节点

返回

指向克隆节点的指针。此指针永远不会为 NULL。

函数 memory_pool::clear

概要

void clear();

描述

清除池。这会导致释放池分配的节点占用的内存。从池中分配的任何节点或字符串将不再有效。

函数 memory_pool::set_allocator

概要

void set_allocator(alloc_func *af, free_func *ff);

描述

设置或重置池的用户定义的内存分配函数。仅当尚未从池中分配内存时,才能调用此函数,否则结果未定义。分配函数不得在失败时返回无效指针。它应该抛出、停止程序或使用 longjmp() 函数将控制权传递给程序的其他位置。如果它返回无效指针,则结果未定义。

用户定义的分配函数必须具有以下形式: void *allocate(std::

size_t size);
void free(void *指针);

参数

自动对焦

分配函数,或 0 恢复默认函数

ff

自由功能,或 0 恢复默认功能

RapidXml::p arse_error 类

在 rapidxml.hpp 中定义

描述

分析错误异常。发生错误时,分析器会引发此异常。使用 what() 函数获取人类可读的错误消息。使用 where() 函数获取指向源文本中检测到错误的位置的指针。

如果不需要解析器引发异常,则可以通过在包含 rapidxml.hpp 之前定义RAPIDXML_NO_EXCEPTIONS宏来禁用它。这将导致解析器调用 rapidxml::p arse_error_handler() 函数,而不是抛出异常。此函数必须由用户定义。

此类派生自 std::exception 类。

构造 函数 parse_error::p arse_error

概要

parse_error(const char *what, void *where);

描述

构造分析错误。

function parse_error::what

Synopsis

virtual const char* what() const;

Description

Gets human readable description of error.

Returns

Pointer to null terminated description of the error.

function parse_error::where

Synopsis

Ch* where() const;

Description

Gets pointer to character data where error happened. Ch should be the same as char type of xml_document that produced the error.

Returns

Pointer to location within the parsed string where error occured.

class template rapidxml::xml_attribute

Defined in rapidxml.hpp
Inherits from xml_base

Description

Class representing attribute node of XML document. Each attribute has name and value strings, which are available through name() and value() functions (inherited from xml_base). Note that after parse, both name and value of attribute will point to interior of source text used for parsing. Thus, this text must persist in memory for the lifetime of attribute.

Parameters

中文

要使用的字符类型。

构造 函数 xml_attribute::xml_attribute

概要

xml_attribute();

描述

构造具有指定类型的空属性。如果手动分配属性,请考虑使用适当xml_document memory_pool。

功能xml_attribute::d ocument

概要

xml_document<Ch>* document() const;

描述

获取哪个属性是子属性的文档。

返回

指向包含此属性的文档的指针,如果没有父文档,则为 0。

函数 xml_attribute::p revious_attribute

概要

xml_attribute<Ch>* previous_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;

描述

获取上一个属性,可以选择匹配属性名称。

参数

名字

要查找的属性的名称,或 0 返回上一个属性,无论其名称如何;如果此字符串为非零,则此字符串不必以零结尾name_size

name_size

名称大小(以字符为单位)或 0 以根据字符串自动计算大小

case_sensitive

名称比较是否应区分大小写;不区分大小写的比较仅适用于 ASCII 字符

返回

指向 found 属性的指针,如果未找到,则为 0。

函数 xml_attribute::next_attribute

概要

xml_attribute<Ch>* next_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;

描述

获取下一个属性,可以选择匹配属性名称。

参数

名字

要查找的属性的名称,或 0 返回下一个属性,无论其名称如何;如果此字符串为非零,则此字符串不必以零结尾name_size

name_size

名称大小(以字符为单位)或 0 以根据字符串自动计算大小

case_sensitive

名称比较是否应区分大小写;不区分大小写的比较仅适用于 ASCII 字符

返回

指向 found 属性的指针,如果未找到,则为 0。

类 模板 RapidXML::xml_base

在 rapidxml.hpp
中定义 xml_attribute xml_node 的基类

描述

用于实现常用函数的 xml_node 和 xml_attribute基类:name()、name_size()、value()、value_size() 和 parent()。

参数

中文

要使用的字符类型

构造 函数 xml_base::xml_base

概要

xml_base();

函数 xml_base::name

概要

Ch* name() const;

描述

获取节点的名称。名称的解释取决于节点的类型。请注意,如果在解析过程中选择了 rapidxml::p arse_no_string_terminators 选项,则 name 不会以零结尾。

使用 name_size() 函数确定名称的长度。

返回

节点的名称,如果节点没有名称,则为空字符串。

函数 xml_base::name_size

概要

std::size_t name_size() const;

描述

获取节点名称的大小,不包括终止符。无论名称是否为零终止,此函数都能正常工作。

返回

节点名称的大小(以字符为单位)。

函数 xml_base::value

概要

Ch* value() const;

描述

获取节点的值。值的解释取决于节点的类型。请注意,如果在解析过程中选择了 rapidxml::p arse_no_string_terminators 选项,则 value 不会以零结尾。

使用 value_size() 函数确定值的长度。

返回

节点的值,如果节点没有值,则为空字符串。

函数 xml_base::value_size

概要

std::size_t value_size() const;

描述

获取节点值的大小,不包括终止符字符。无论 value 是否为零终止,此函数都能正常工作。

返回

节点值的大小(以字符为单位)。

函数 xml_base::name

概要

void name(const Ch *name, std::size_t size);

描述

将节点名称设置为非以零结尾的字符串。请参 阅字符串的所有权 。

请注意,节点不拥有其名称或值,它只存储指向它的指针。它不会在销毁时删除或以其他方式释放指针。用户有责任正确管理字符串的生存期。实现它的最简单方法是使用文档的memory_pool来分配字符串 - 在文档销毁时,字符串将自动释放。

必须单独指定 name 的大小,因为 name 不必以零结尾。使用 name(const Ch *) 函数自动计算长度(字符串必须以零结尾)。

参数

名字

要设置的节点的名称。不必为零终止。

大小

名称的大小,以字符为单位。如果存在零终止符,则不包括零终止符。

函数 xml_base::name

概要

void name(const Ch *name);

描述

将节点名称设置为以零结尾的字符串。另请参阅 Ownership Of Strings 和 xml_node::name(const Ch *, std::size_t)。

参数

名字

要设置的节点的名称。必须以零终止。

函数 xml_base::value

概要

void value(const Ch *value, std::size_t size);

描述

将 node 的值设置为非以零结尾的字符串。请参 阅字符串的所有权 。

请注意,节点不拥有其名称或值,它只存储指向它的指针。它不会在销毁时删除或以其他方式释放指针。用户有责任正确管理字符串的生存期。实现它的最简单方法是使用文档的memory_pool来分配字符串 - 在文档销毁时,字符串将自动释放。

值的大小必须单独指定,因为它不必以零结尾。使用 value(const Ch *) 函数自动计算长度(字符串必须以零结尾)。

如果元素具有 node_data 类型的子节点,则在打印时它将优先于元素值。如果要使用值操作元素的数据,请使用解析器标志 rapidxml::p arse_no_data_nodes 来防止解析器创建数据节点。

参数

价值

要设置的节点的值。不必为零终止。

大小

值的大小(以字符为单位)。如果存在零终止符,则不包括零终止符。

函数 xml_base::value

概要

void value(const Ch *value);

描述

将 node 的值设置为以零结尾的字符串。另请参阅 Ownership Of Strings 和 xml_node::value(const Ch *, std::size_t)。

参数

价值

要设置的节点的 Vame。必须以零终止。

函数 xml_base::p arent

概要

xml_node<Ch>* parent() const;

描述

获取节点父级。

返回

指向父节点的指针,如果没有父节点,则为 0。

类 模板 RapidXML::xml_document

在 rapidxml.hpp
中定义 继承自 xml_node memory_pool

描述

此类表示 DOM 层次结构的根。它也是通过公共继承xml_node和memory_pool。使用 parse() 函数从以零结尾的 XML 文本字符串构建 DOM 树。parse() 函数使用 xml_document 函数为节点和属性分配内存,这些函数继承自 memory_pool。若要访问文档的根节点,请使用文档本身,就像它是xml_node一样。

参数

中文

要使用的字符类型。

构造 函数 xml_document::xml_document

概要

xml_document();

描述

构造空的 XML 文档。

函数xml_document::p arse

概要

void parse(Ch *text);

描述

根据给定的标志分析以零结尾的 XML 字符串。传递的字符串将被解析器修改,除非使用 rapidxml::p arse_non_destructive 标志。该字符串必须在文档的生存期内保留。如果出现错误,将抛出 rapidxml::p arse_error 异常。

如果要分析文件的内容,必须首先将文件加载到内存中,然后传递指向其开头的指针。确保数据以零终止。

文档可以解析为多次。每次对 parse 的新调用都会删除以前的节点和属性(如果有),但不会清除内存池。

参数

发短信

要解析的 XML 数据;指针是非常量,表示此数据可能被解析器修改的事实。

函数 xml_document::clear

概要

void clear();

描述

通过删除所有节点并清除内存池来清除文档。文档池拥有的所有节点都将被销毁。

类 模板 RapidXML::xml_node

在 rapidxml.hpp
中定义 继承自 xml_document xml_base
基类

描述

表示 XML 文档节点的类。每个节点可能具有关联的名称和值字符串,这些字符串可通过 name() 和 value() 函数获得。名称和值的解释取决于节点的类型。可以使用 type() 函数确定节点类型。

请注意,解析后,节点的名称和值(如果有)都将指向用于解析的源文本的内部。因此,此文本必须在节点的生存期内保留在内存中。

参数

中文

要使用的字符类型。

构造 函数 xml_node::xml_node

概要

xml_node(node_type type);

描述

构造具有指定类型的空节点。请考虑使用memory_pool适当的文档来手动分配节点。

参数

类型

要构造的节点的类型。

函数 xml_node::type

概要

node_type type() const;

描述

获取节点的类型。

返回

节点类型。

功能xml_node::d ocument

概要

xml_document<Ch>* document() const;

描述

获取哪个节点是子节点的文档。

返回

指向包含此节点的文档的指针,如果没有父文档,则为 0。

函数 xml_node::first_node

概要

xml_node<Ch>* first_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;

描述

获取第一个子节点,可以选择匹配节点名称。

参数

名字

要查找的子项的名称,或返回第一个子项的 0,无论其名称如何;如果此字符串为非零,则此字符串不必以零结尾name_size

name_size

名称大小(以字符为单位)或 0 以根据字符串自动计算大小

case_sensitive

名称比较是否应区分大小写;不区分大小写的比较仅适用于 ASCII 字符

返回

指向已找到子项的指针,如果未找到,则为 0。

函数 xml_node::last_node

概要

xml_node<Ch>* last_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;

描述

获取最后一个子节点,可以选择匹配节点名称。如果节点没有子节点,则行为未定义。使用 first_node() 测试节点是否有子节点。

参数

名字

要查找的子项的名称,或 0 返回最后一个子项,无论其名称如何;如果此字符串为非零,则此字符串不必以零结尾name_size

name_size

名称大小(以字符为单位)或 0 以根据字符串自动计算大小

case_sensitive

名称比较是否应区分大小写;不区分大小写的比较仅适用于 ASCII 字符

返回

指向已找到子项的指针,如果未找到,则为 0。

函数 xml_node::p revious_sibling

概要

xml_node<Ch>* previous_sibling(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;

描述

获取上一个同级节点,可以选择匹配节点名称。如果节点没有父节点,则行为未定义。使用 parent() 测试节点是否有父节点。

参数

名字

要查找的兄弟姐妹的名称,或 0 返回上一个兄弟姐妹,无论其名称如何;如果此字符串为非零,则此字符串不必以零结尾name_size

name_size

名称大小(以字符为单位)或 0 以根据字符串自动计算大小

case_sensitive

名称比较是否应区分大小写;不区分大小写的比较仅适用于 ASCII 字符

返回

指向已找到同级的指针,如果未找到,则为 0。

函数 xml_node::next_sibling

概要

xml_node<Ch>* next_sibling(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;

描述

获取下一个同级节点,可以选择匹配节点名称。如果节点没有父节点,则行为未定义。使用 parent() 测试节点是否有父节点。

参数

名字

要查找的兄弟姐妹的名称,或 0 返回下一个兄弟姐妹,无论其名称如何;如果此字符串为非零,则此字符串不必以零结尾name_size

name_size

名称大小(以字符为单位)或 0 以根据字符串自动计算大小

case_sensitive

名称比较是否应区分大小写;不区分大小写的比较仅适用于 ASCII 字符

返回

指向已找到同级的指针,如果未找到,则为 0。

函数 xml_node::first_attribute

概要

xml_attribute<Ch>* first_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;

描述

获取节点的第一个属性,可以选择匹配属性名称。

参数

名字

要查找的属性的名称,或 0 返回第一个属性,无论其名称如何;如果此字符串为非零,则此字符串不必以零结尾name_size

name_size

名称大小(以字符为单位)或 0 以根据字符串自动计算大小

case_sensitive

名称比较是否应区分大小写;不区分大小写的比较仅适用于 ASCII 字符

返回

指向 found 属性的指针,如果未找到,则为 0。

函数 xml_node::last_attribute

概要

xml_attribute<Ch>* last_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;

描述

获取节点的最后一个属性,可以选择匹配属性名称。

参数

名字

要查找的属性的名称,或 0 返回最后一个属性,无论其名称如何;如果此字符串为非零,则此字符串不必以零结尾name_size

name_size

名称大小(以字符为单位)或 0 以根据字符串自动计算大小

case_sensitive

名称比较是否应区分大小写;不区分大小写的比较仅适用于 ASCII 字符

返回

指向 found 属性的指针,如果未找到,则为 0。

函数 xml_node::type

概要

void type(node_type type);

描述

设置节点的类型。

参数

类型

要设置的节点类型。

函数 xml_node::p repend_node

概要

void prepend_node(xml_node< Ch > *child);

描述

预置新的子节点。前面的子项成为第一个子项,所有现有子项都向后移动一个位置。

参数

孩子

要预置的节点。

函数 xml_node::append_node

概要

void append_node(xml_node< Ch > *child);

描述

追加新的子节点。附加的子项成为最后一个子项。

参数

孩子

要追加的节点。

函数 xml_node::insert_node

概要

void insert_node(xml_node< Ch > *where, xml_node< Ch > *child);

描述

在节点内的指定位置插入新的子节点。指定节点之后(包括指定节点)的所有子节点都将向后移动一个位置。

参数

哪里

放置插入孩子的位置,或 0 插入到后面。

孩子

要插入的节点。

函数 xml_node::remove_first_node

概要

void remove_first_node();

描述

删除第一个子节点。如果节点没有子节点,则行为未定义。使用 first_node() 测试节点是否有子节点。

函数 xml_node::remove_last_node

概要

void remove_last_node();

描述

删除节点的最后一个子节点。如果节点没有子节点,则行为未定义。使用 first_node() 测试节点是否有子节点。

函数 xml_node::remove_node

概要

void remove_node(xml_node< Ch > *where);

描述

从节点中删除指定的子节点。

函数 xml_node::remove_all_nodes

概要

void remove_all_nodes();

描述

删除所有子节点(但不包括属性)。

函数 xml_node::p repend_attribute

概要

void prepend_attribute(xml_attribute< Ch > *attribute);

描述

将新属性追加到节点。

参数

属性

要预置的属性。

函数 xml_node::append_attribute

概要

void append_attribute(xml_attribute< Ch > *attribute);

Description

Appends a new attribute to the node.

Parameters

attribute

Attribute to append.

function xml_node::insert_attribute

Synopsis

void insert_attribute(xml_attribute< Ch > *where, xml_attribute< Ch > *attribute);

Description

Inserts a new attribute at specified place inside the node. All attributes after and including the specified attribute are moved one position back.

Parameters

where

Place where to insert the attribute, or 0 to insert at the back.

attribute

Attribute to insert.

function xml_node::remove_first_attribute

概要

void remove_first_attribute();

描述

删除节点的第一个属性。如果节点没有属性,则行为未定义。使用 first_attribute() 测试节点是否具有属性。

函数 xml_node::remove_last_attribute

概要

void remove_last_attribute();

描述

删除节点的最后一个属性。如果节点没有属性,则行为未定义。使用 first_attribute() 测试节点是否具有属性。

函数 xml_node::remove_attribute

概要

void remove_attribute(xml_attribute< Ch > *where);

描述

从节点中删除指定的属性。

参数

哪里

指向要删除的属性的指针。

函数 xml_node::remove_all_attributes

概要

void remove_all_attributes();

描述

删除节点的所有属性。

枚举node_type

描述

枚举列出分析器生成的所有节点类型。使用 xml_node::type() 函数查询节点类型。

node_document

文档节点。名称和值为空。

node_element

元素节点。Name 包含元素名称。值包含第一个数据节点的文本。

node_data

数据节点。名称为空。值包含数据文本。

node_cdata

CDATA 节点。名称为空。值包含数据文本。

node_comment

注释节点。名称为空。值包含注释文本。

node_declaration

声明节点。名称和值为空。声明参数(version、encoding 和 standalone)位于节点属性中。

node_doctype

一个 DOCTYPE 节点。名称为空。值包含 DOCTYPE 文本。

node_pi

PI 节点。名称包含目标。值包含指令。

功能parse_error_handler

概要

void rapidxml::parse_error_handler(const char *what, void *where);

描述

当通过定义RAPIDXML_NO_EXCEPTIONS禁用异常时,将调用此函数以通知用户有关错误的信息。它必须由用户定义。

此函数无法返回。如果是这样,则结果是不确定的。

一个非常简单的定义可能看起来像这样: void rapidxml::p arse_error_handler(const char *what, void *where) { std::cout << “解析错误:” << what << “\n”; std::abort(); }

参数

什么

人类可读的错误描述。

哪里

指向检测到错误的字符数据的指针。

功能打印

概要

OutIt rapidxml::print(OutIt out, const xml_node< Ch > &node, int flags=0);

描述

将 XML 打印到给定的输出迭代器。

参数

要打印到的输出迭代器。

节点

要打印的节点。传递xml_document以打印整个文档。

标志

控制 XML 打印方式的标志。

返回

输出迭代器,指向紧跟在打印文本最后一个字符之后的位置。

功能打印

概要

std::basic_ostream<Ch>& rapidxml::print(std::basic_ostream< Ch > &out, const xml_node< Ch > &node, int flags=0);

描述

将 XML 打印到给定的输出流。

参数

要打印到的输出流。

节点

要打印的节点。传递xml_document以打印整个文档。

标志

控制 XML 打印方式的标志。

返回

输出流。

函数运算符<<

概要

std::basic_ostream<Ch>& rapidxml::operator<<(std::basic_ostream< Ch > &out, const xml_node< Ch > &node);

描述

将格式化的 XML 打印到给定的输出流。使用默认打印标志。使用 print() 函数自定义打印过程。

参数

要打印到的输出流。

节点

要打印的节点。

返回

输出流。

parse_no_data_nodes

概要

const int parse_no_data_nodes = 0x1;

描述

Parse 标志指示解析器不创建数据节点。第一个数据节点的文本仍将放置在父元素的值中,除非还指定了 rapidxml::p arse_no_element_values 标志。可以使用 |算子。

参见 xml_document::p arse() 函数。

parse_no_element_values

概要

const int parse_no_element_values = 0x2;

描述

Parse 标志指示解析器不要使用第一个数据节点的文本作为父元素的值。可以使用 |算子。请注意,打印时元素节点的子数据节点优先于其值。也就是说,如果元素具有一个或多个子数据节点和一个值,则该值将被忽略。如果要使用元素值操作数据,请使用 rapidxml::p arse_no_data_nodes 标志来阻止创建数据节点。

参见 xml_document::p arse() 函数。

parse_no_string_terminators

概要

const int parse_no_string_terminators = 0x4;

描述

parse 标志指示分析器不要在源文本中的字符串后放置零终止符。默认情况下,将放置零个终止符,以修改源文本。可以使用 |算子。

参见 xml_document::p arse() 函数。

parse_no_entity_translation

概要

const int parse_no_entity_translation = 0x8;

描述

Parse 标志指示分析器不翻译源文本中的实体。默认情况下,将翻译实体,修改源文本。可以使用 |算子。

参见 xml_document::p arse() 函数。

parse_no_utf8

概要

const int parse_no_utf8 = 0x10;

描述

Parse 标志指示解析器禁用 UTF-8 处理并假定纯 8 位字符。默认情况下,UTF-8 处理处于启用状态。可以使用 |算子。

参见 xml_document::p arse() 函数。

parse_declaration_node

概要

const int parse_declaration_node = 0x20;

描述

指示解析器创建 XML 声明节点的 parse 标志。缺省情况下,不创建声明节点。可以使用 |算子。

参见 xml_document::p arse() 函数。

parse_comment_nodes

概要

const int parse_comment_nodes = 0x40;

描述

Parse 标志指示解析器创建注释节点。缺省情况下,不创建注释节点。可以使用 |算子。

参见 xml_document::p arse() 函数。

parse_doctype_node

概要

const int parse_doctype_node = 0x80;

描述

解析标志指示解析器创建 DOCTYPE 节点。缺省情况下,不会创建 doctype 节点。尽管 W3C 规范最多允许一个 DOCTYPE 节点,但 RapidXml 将静默地接受具有多个节点的文档。可以使用 |算子。

参见 xml_document::p arse() 函数。

parse_pi_nodes

概要

const int parse_pi_nodes = 0x100;

描述

指示解析器创建 PI 节点的解析标志。默认情况下,不会创建 PI 节点。可以使用 |算子。

参见 xml_document::p arse() 函数。

parse_validate_closing_tags

概要

const int parse_validate_closing_tags = 0x200;

描述

Parse 标志指示分析器验证结束标记名称。如果未设置,则结束标记内的名称与解析器无关。默认情况下,不会验证结束标记。可以使用 |算子。

参见 xml_document::p arse() 函数。

parse_trim_whitespace

概要

const int parse_trim_whitespace = 0x400;

描述

Parse 标志指示解析器修剪数据节点的所有前导和尾随空格。默认情况下,不会修剪空格。此标志不会导致分析器修改源文本。可以使用 |算子。

参见 xml_document::p arse() 函数。

parse_normalize_whitespace

概要

const int parse_normalize_whitespace = 0x800;

描述

Parse 标志指示解析器将数据节点的所有空格运行压缩为单个空格字符。数据的前导和尾随空格的修剪由 rapidxml::p arse_trim_whitespace 标志控制。默认情况下,空格不会规范化。如果指定了此标志,则将修改源文本。可以使用 |算子。

参见 xml_document::p arse() 函数。

parse_default

概要

const int parse_default = 0;

描述

解析标志,表示解析器的默认行为。这始终等于 0,因此所有其他标志可以简单地组合在一起。通常,没有必要通过使用其否定 (~) 值来禁用标志,从而不方便地禁用标志。这也意味着每个标志的含义都是对默认设置的否定。例如,如果标志名称为 rapidxml::p arse_no_utf8,则表示默认启用 utf-8,使用该标志将禁用它。

参见 xml_document::p arse() 函数。

parse_non_destructive

概要

const int parse_non_destructive = parse_no_string_terminators | parse_no_entity_translation;

描述

禁止对源文本进行任何修改的分析标志的组合。这也导致更快的解析。但是,请注意,将发生以下情况:

  • 节点的名称和值不会以零结尾,您必须使用 xml_base::name_size() 和 xml_base::value_size() 函数来确定名称和值的结束位置
  • 实体不会被翻译
  • 空格不会被规范化

参见 xml_document::p arse() 函数。

parse_fastest

概要

const int parse_fastest = parse_non_destructive | parse_no_data_nodes;

描述

解析标志的组合可在不牺牲重要数据的情况下实现尽可能快的解析。

参见 xml_document::p arse() 函数。

parse_full

概要

const int parse_full = parse_declaration_node | parse_comment_nodes | parse_doctype_node | parse_pi_nodes | parse_validate_closing_tags;

描述

分析标志的组合,导致提取的数据量最大。这通常会导致解析速度最慢。

参见 xml_document::p arse() 函数。

print_no_indenting

概要

const int print_no_indenting = 0x1;

描述

指示打印机禁止缩进 XML 的打印机标志。请参阅 print() 函数。

C笔记

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/249741.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

纽扣电池是什么

纽扣电池 电工电气百科 文章目录 纽扣电池前言一、纽扣电池是什么二、纽扣电池的类别三、纽扣电池的作用原理总结前言 纽扣电池具有易于更换的特点,这使得它们成为许多便携设备的理想电源选择。但是,由于它们较小且外壳易于打开,所以家中有婴幼儿的家庭应特别注意将其放置在…

云原生之深入解析亿级流量架构之服务限流思路与方法

一、限流思路 ① 熔断 系统在设计之初就把熔断措施考虑进去&#xff0c;当系统出现问题时&#xff0c;如果短时间内无法修复&#xff0c;系统要自动做出判断&#xff0c;开启熔断开关&#xff0c;拒绝流量访问&#xff0c;避免大流量对后端的过载请求。系统也应该能够动态监测…

Pycharm第三方库导入失败避坑!

最近遇到了明明安装了 python 第三方库&#xff0c;但是在 pycharm 当中却导入不成功的问题。 使用Pycharm手动安装三方库和自动安装三方库都失败&#xff0c;以及Pycharm终端使用pip命令安装也未解决。网上找各种方法尝试都没成功&#xff0c;原来是一不小心就跳进了虚拟环境…

代码随想录算法训练营 | day52 动态规划 300.最长递增子序列,674.最长连续递增子序列,718.最长重复子数组

刷题 300.最长递增子序列 题目链接 | 文章讲解 | 视频讲解 题目&#xff1a;给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。…

彻底告别pip安装Python第三方库网速慢的问题

方式一、 如果使只下载没几个库 直接: pip install 库名 -i http://mirrors.aliyun.com/pypi/simple/ 方式二、 如果要一直下载库&#xff0c;就可以通过配置pip.ini文件来解决&#xff0c;具体步骤如下所示&#xff1a; 1、打开文件资源管理器 2、搜索%APPDATE% 3、创建一…

LeetCode 2415. 反转二叉树的奇数层:深度优先搜索(DFS)

【LetMeFly】2415.反转二叉树的奇数层&#xff1a;深度优先搜索(DFS) 力扣题目链接&#xff1a;https://leetcode.cn/problems/reverse-odd-levels-of-binary-tree/ 给你一棵 完美 二叉树的根节点 root &#xff0c;请你反转这棵树中每个 奇数 层的节点值。 例如&#xff0c…

CSS盒子的浮动与网页布局(重点,有电影页面案例)

浮动适用于那种盒子的并列布局 CSS 提供了三种传统布局方式(简单说,就是盒子如何进行排列顺序)&#xff1a;  普通流&#xff08;标准流&#xff09;  浮动  定位 标准流&#xff08;普通流/文档流&#xff09; 所谓的标准流: 就是标签按照规定好默认方式排列. 1. 块级…

win10电脑字体大小怎么设置?介绍四种方法

在Win10操作系统中&#xff0c;字体大小的设置对于用户来说是一个非常重要的问题。合适的字体大小能够保护我们的视力&#xff0c;提高我们的工作效率。本文将介绍几种常用的方法来调整Win10电脑的字体大小&#xff0c;帮助用户轻松设置自己喜欢的字体大小。 方法一&#xff1…

C语言写的 mini版的 http 服务器 , 很详细

文章目录 效果展示整体架构流程技术细节完整代码 效果展示 例如&#xff1a;htpp://192.168.23.140/home.html -> 正确的请求格式 home.html 这个资源是放在我们服务器里面的 , 并不是随便访问的资源,当然我们可以放很多的资源进去. 整体架构流程 整个实现的流…

源码解析:Apache RocketMQ重置消费位点

引入 reset offset&#xff0c;即重置消费进度&#xff0c;一般在以下场景中使用&#xff1a; 需要重新消费已经消费过的消息&#xff0c;重置到最早位置或根据时间进行重置。消息积压&#xff0c;不需要消费积压的消息&#xff0c;重置到最新位置&#xff0c;使其从最新位置…

订单管理系统开发经验的总结:优化流程、提升效率的关键实践

前言 一.订单管理系统的架构设计 二.订单系统的详细设计 1.拆分 2.换货 3.发货 4.拦截 5.取消 6.物流回传 三.订单系统的订单状态流转 初始状态 中间状态 异常状态 终态 四.订单系统的关键代码逻辑 五.结语 前言 两年来&#xff0c;整个订单管理系统经过大大小…

[MySQL]数据库概述

目录 1.什么是数据库 2.数据库分类 2.1关系型数据库 2.2非关系型数据库 1.什么是数据库 我们知道&#xff0c;存储数据可以使用文件来存储。那么为什么我们还要大费周章的去设计和使用数据库呢&#xff1f; 因为文件保存数据有以下几个缺点&#xff1a; 1.文件的安全性不…

Attention机制学习

写在前面 注意力机制是一个很不错的科研创新点方向&#xff0c;但是没有系统记录过学习过程&#xff0c;这里记录科研中遇到的各种注意力机制。 1. Attention机制解释 本质上来说用到attention的任务都有Query&#xff0c;Key&#xff0c;Value三个关键components&#xff0c;…

扩展学习|大数据挖掘与智能体ABM建模

出处&#xff1a;计算社会科学_中南大学_中国大学MOOC(慕课) (icourse163.org)https://www.icourse163.org/course/CSU-1466004186 ps&#xff1a;相关内容来自于本人笔记&#xff0c;若有需要请联系原作者&#xff01;个人学习留存&#xff0c;侵权必删&#xff01; 一…

可回收资源的环保螺旋盖葡萄酒

在酿酒师中&#xff0c;选择哪种瓶盖来保存一瓶葡萄酒主要取决于葡萄酒的种类和酿酒师自己的偏好。在20世纪70年代&#xff0c;澳洲朋友引进并推广了一种保存葡萄酒的新方法&#xff0c;这种新方法螺旋盖并在70年代获得专利&#xff0c;投入商业使用&#xff0c;澳大利亚的酿酒…

【STM32】STM32学习笔记-OLED显示屏(10)

00. 目录 文章目录 00. 目录01. OLED显示屏接线图02. OLED函数库03. OLED测试代码04. Keil调试05. 程序下载06. 附录 01. OLED显示屏接线图 02. OLED函数库 oled.h #ifndef __OLED_H #define __OLED_Hvoid OLED_Init(void); void OLED_Clear(void); void OLED_ShowChar(uint8…

图片变成动图如何操作?掌握这个办法就够了

生动有趣的gif动画图片是怎么制作的呢&#xff1f;其实&#xff0c;制作gif动图的方法很简单&#xff0c;无需下载任何软件&#xff0c;使用gif动图制作&#xff08;https://www.gif.cn/&#xff09;工具-GIF中文网。只需要上传jpg、png格式的图片&#xff0c;轻松一键就能在线…

Reinfocement Learning 学习笔记PartⅡ

文章目录 Reinfocement Learning六、随机近似与随机梯度下降&#xff08;Stochastic Approximation & Stochastic Gradient Descent&#xff09;6.1 Robbins-Monro Algorithm6.2 随机梯度下降 七、时序差分方法&#xff08;Temporal-Difference Learning&#xff09;7.1 TD…

OpenAI 承认 ChatGPT 最近的懒惰:由于用户体验到响应缓慢和无用的输出,调查正在进行中

文章目录 一. ChatGPT 指令遵循能力下降引发用户投诉1.1 用户抱怨回应速度慢、敷衍回答、拒绝回答和中断会话 二. OpenAI 官方确认 ChatGPT 存在问题&#xff0c;展开调查三. OpenAI 解释模型行为差异&#xff0c;回应用户质疑四. GPT-4 模型变更受人事动荡和延期影响 一. Chat…

【设计模式--行为型--中介者模式】

设计模式--行为型--中介者模式 中介者模式定义结构案例实现优缺点使用场景 中介者模式 定义 又叫调停模式&#xff0c;定义一个中介角色来封装一系列对象之间的交互&#xff0c;使原有对象之间的耦合松散&#xff0c;且可以独立的改变它们之间的交互。 结构 抽象中介者角色…