Commit 9c710935 authored by Milo Yip's avatar Milo Yip

Merge pull request #482 from macworld/master

fix typos and dead links in docs
parents 9d47c623 06f62e38
......@@ -106,59 +106,59 @@
Call one of the `SetXXX()` methods - they call destructor which deallocates DOM data:
```
~~~~~~~~~~cpp
Document d;
...
d.SetObject(); // clear and minimize
```
~~~~~~~~~~
Alternatively, use equivalent of the [C++ swap with temporary idiom](https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Clear-and-minimize):
```
~~~~~~~~~~cpp
Value(kObjectType).Swap(d);
```
~~~~~~~~~~
or equivalent, but sightly longer to type:
```
~~~~~~~~~~cpp
d.Swap(Value(kObjectType).Move());
```
~~~~~~~~~~
9. How to insert a document node into another document?
Let's take the following two DOM trees represented as JSON documents:
```
~~~~~~~~~~cpp
Document person;
person.Parse("{\"person\":{\"name\":{\"first\":\"Adam\",\"last\":\"Thomas\"}}}");
Document address;
address.Parse("{\"address\":{\"city\":\"Moscow\",\"street\":\"Quiet\"}}");
```
~~~~~~~~~~
Let's assume we want to merge them in such way that the whole `address` document becomes a node of the `person`:
```
~~~~~~~~~~js
{ "person": {
"name": { "first": "Adam", "last": "Thomas" },
"address": { "city": "Moscow", "street": "Quiet" }
}
}
```
~~~~~~~~~~
The most important requirement to take care of document and value life-cycle as well as consistent memory managent using the right allocator during the value transfer.
Simple yet most efficient way to achieve that is to modify the `address` definition above to initialize it with allocator of the `person` document, then we just add the root nenber of the value:
```
Simple yet most efficient way to achieve that is to modify the `address` definition above to initialize it with allocator of the `person` document, then we just add the root member of the value:
~~~~~~~~~~cpp
Documnet address(person.GetAllocator());
...
person["person"].AddMember("address", address["address"], person.GetAllocator());
```
~~~~~~~~~~
Alternatively, if we don't want to explicitly refer to the root value of `address` by name, we can refer to it via iterator:
```
~~~~~~~~~~cpp
auto addressRoot = address.MemberBegin();
person["person"].AddMember(addressRoot->name, addressRoot->value, person.GetAllocator());
```
~~~~~~~~~~
Second way is to deep-clone the value from the address document:
```
~~~~~~~~~~cpp
Value addressValue = Value(address["address"], person.GetAllocator());
person["person"].AddMember("address", addressValue, person.GetAllocator());
```
~~~~~~~~~~
## Document/Value (DOM)
......
......@@ -28,7 +28,7 @@
6. 怎样安装RapidJSON?
[安装一节](readme.zh-cn.md)
[安装一节](../readme.zh-cn.md#安装)
7. RapidJSON能否运行于我的平台?
......@@ -52,7 +52,7 @@
12. 有没有其他替代品?
有许多替代品。例如nativejson-benchmark](https://github.com/miloyip/nativejson-benchmark)列出了一些开源的C/C++ JSON库。[json.org](http://www.json.org/)也有一个列表。
有许多替代品。例如[nativejson-benchmark](https://github.com/miloyip/nativejson-benchmark)列出了一些开源的C/C++ JSON库。[json.org](http://www.json.org/)也有一个列表。
## JSON
......@@ -98,10 +98,69 @@
错误信息存储在`ParseResult`,它包含错误代号及偏移值(从JSON开始至错误处的字符数目)。可以把错误代号翻译为人类可读的错误讯息。
7.不只使用`double`去表示JSON number?
7.不只使用`double`去表示JSON number?
一些应用需要使用64位无号/有号整数。这些整数不能无损地转换成`double`。因此解析器会检测一个JSON number是否能转换至各种整数类型及`double`
8. 如何清空并最小化`document``value`的容量?
调用 `SetXXX()` 方法 - 这些方法会调用析构函数,并重建空的Object或Array:
~~~~~~~~~~cpp
Document d;
...
d.SetObject(); // clear and minimize
~~~~~~~~~~
另外,也可以参考在 [C++ swap with temporary idiom](https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Clear-and-minimize)中的一种等价的方法:
~~~~~~~~~~cpp
Value(kObjectType).Swap(d);
~~~~~~~~~~
或者,使用这个稍微长一点的代码也能完成同样的事情:
~~~~~~~~~~cpp
d.Swap(Value(kObjectType).Move());
~~~~~~~~~~
9. 如何将一个`document`节点插入到另一个`document`中?
比如有以下两个document(DOM):
~~~~~~~~~~cpp
Document person;
person.Parse("{\"person\":{\"name\":{\"first\":\"Adam\",\"last\":\"Thomas\"}}}");
Document address;
address.Parse("{\"address\":{\"city\":\"Moscow\",\"street\":\"Quiet\"}}");
~~~~~~~~~~
假设我们希望将整个 `address` 插入到`person`中,作为其的一个子节点:
~~~~~~~~~~js
{ "person": {
"name": { "first": "Adam", "last": "Thomas" },
"address": { "city": "Moscow", "street": "Quiet" }
}
}
~~~~~~~~~~
在插入节点的过程中需要注意`document``value`的生命周期并且正确地使用allocator进行内存分配和管理。
一个简单有效的方法就是修改上述`address`变量的定义,让其使用`person`的allocator初始化,然后将其添加到根节点。
~~~~~~~~~~cpp
Documnet address(person.GetAllocator());
...
person["person"].AddMember("address", address["address"], person.GetAllocator());
~~~~~~~~~~
当然,如果你不想通过显式地写出`address`的key来得到其值,可以使用迭代器来实现:
~~~~~~~~~~cpp
auto addressRoot = address.MemberBegin();
person["person"].AddMember(addressRoot->name, addressRoot->value, person.GetAllocator());
~~~~~~~~~~
此外,还可以通过深拷贝address document来实现:
~~~~~~~~~~cpp
Value addressValue = Value(address["address"], person.GetAllocator());
person["person"].AddMember("address", addressValue, person.GetAllocator());
~~~~~~~~~~
## Document/Value (DOM)
1. 什么是转移语意?为什么?
......
......@@ -175,7 +175,7 @@ bool Parse(InputStream& is, Handler& handler);
# Writer {#Writer}
`Reader`把JSON转换(解析)成为事件。`Writer`完全做相反的事情。它把事件转换成JSON。
`Reader`把JSON转换(解析)成为事件。`Writer`做完全相反的事情。它把事件转换成JSON。
`Writer`是非常容易使用的。若你的应用程序只需把一些数据转换成JSON,可能直接使用`Writer`,会比建立一个`Document`然后用`Writer`把它转换成JSON更加方便。
......@@ -265,7 +265,7 @@ public:
## PrettyWriter {#PrettyWriter}
`Writer`所输出的是没有空格字符的最紧凑JSON,适合网络传输或储存,但适合人类阅读。
`Writer`所输出的是没有空格字符的最紧凑JSON,适合网络传输或储存,但适合人类阅读。
因此,RapidJSON提供了一个`PrettyWriter`,它在输出中加入缩进及换行。
......@@ -386,13 +386,13 @@ Error: Terminate parsing due to Handler error.
at offset 59 near '} }...'
~~~~~~~~~~
第一个JSON(`json1`)被成功地解析至`MessageMap`。由于`MessageMap`是一个`std::map`印次序按键值排序。此次序与JSON中的次序不同。
第一个JSON(`json1`)被成功地解析至`MessageMap`。由于`MessageMap`是一个`std::map`印次序按键值排序。此次序与JSON中的次序不同。
在第二个JSON(`json2`)中,`foo`的值是一个空object。由于它是一个object,`MessageHandler::StartObject()`会被调用。然而,在`state_ = kExpectValue`的情况下,该函数会返回`false`,并令到解析过程终止。错误代码是`kParseErrorTermination`
在第二个JSON(`json2`)中,`foo`的值是一个空object。由于它是一个object,`MessageHandler::StartObject()`会被调用。然而,在`state_ = kExpectValue`的情况下,该函数会返回`false`,并导致解析过程终止。错误代码是`kParseErrorTermination`
## 过滤JSON {#Filtering}
如前面提及过,`Writer`可处理`Reader`发出的事件。`condense`例子简单地设置`Writer`作为一个`Reader`的处理器,因此它能移除JSON中的所有空白字符。`pretty`例子使用同样的关系,只是以`PrettyWriter`取代`Writer`。因此`pretty`能够重新格式化JSON,加入缩进及换行。
如前面提及过,`Writer`可处理`Reader`发出的事件。`example/condense/condense.cpp`例子简单地设置`Writer`作为一个`Reader`的处理器,因此它能移除JSON中的所有空白字符。`example/pretty/pretty.cpp`例子使用同样的关系,只是以`PrettyWriter`取代`Writer`。因此`pretty`能够重新格式化JSON,加入缩进及换行。
实际上,我们可以使用SAX风格API去加入(多个)中间层去过滤JSON的内容。例如`capitalize`例子可以把所有JSON string改为大写。
......@@ -472,5 +472,5 @@ int main(int, char*[]) {
["HELLO\nWORLD"]
~~~~~~~~~~
我们还可以开发更复杂的过滤器。然而,由于SAX风格API在某一时间点只能提供单一事件的信息,使用者需要自行记录一些上下文信息(例如从根节点起的路径、储存其他相关值)。对些一些处理情况,用DOM会比SAX更容易实现。
我们还可以开发更复杂的过滤器。然而,由于SAX风格API在某一时间点只能提供单一事件的信息,使用者需要自行记录一些上下文信息(例如从根节点起的路径、储存其他相关值)。对于处理某些情况,用DOM会比SAX更容易实现。
......@@ -2,7 +2,7 @@
本教程简介文件对象模型(Document Object Model, DOM)API。
[用法一览](readme.zh-cn.md)中所示,可以解析一个JSON至DOM,然后就可以轻松查询及修改DOM,并最终转换回JSON。
[用法一览](../readme.zh-cn.md#用法一览)中所示,可以解析一个JSON至DOM,然后就可以轻松查询及修改DOM,并最终转换回JSON。
[TOC]
......@@ -123,7 +123,7 @@ a[3] = 4
你可以用整数字面量访问元素,如`a[0]``a[1]``a[2]`
Array与`std::vector`相似,除了使用索引,也可使用迭器来访问所有元素。
Array与`std::vector`相似,除了使用索引,也可使用迭器来访问所有元素。
~~~~~~~~~~cpp
for (Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
printf("%d ", itr->GetInt());
......@@ -461,7 +461,7 @@ contact.AddMember(key, val, document.GetAllocator());
* `bool RemoveMember(const Ch* name)`:使用键名来移除成员(线性时间复杂度)。
* `bool RemoveMember(const Value& name)`:除了`name`是一个Value,和上一行相同。
* `MemberIterator RemoveMember(MemberIterator)`:使用迭器移除成员(_常数_时间复杂度)。
* `MemberIterator RemoveMember(MemberIterator)`:使用迭器移除成员(_常数_时间复杂度)。
* `MemberIterator EraseMember(MemberIterator)`:和上行相似但维持成员次序(线性时间复杂度)。
* `MemberIterator EraseMember(MemberIterator first, MemberIterator last)`:移除一个范围内的成员,维持次序(线性时间复杂度)。
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment