Pugi解析XML很快,主要是因为它牺牲了部分功能,举个简单的例子就是,它不能获取某个节点的行号,列号。
本文提供一种方法,计算出行列号。主要使用pugi中函数offset_debug()。
官方解释:
获取节点的偏移量,单位是 chat_t。
注意下图,红色的话,chat_t分窄字符和宽字符,长度分别为1byte 和2byte。
// Get node offset in parsed file/string (in char_t units) for debugging purposes
ptrdiff_t offset_debug() const;
获取行号的原理:
很简单,通过offse_debug获得字符序号,查找字符序号所在的行。
1.我们把每行的最末尾的字符序号记录下来;(建立一个vector :build_offset_data)
2.找到那个末尾序号刚大于这个序号的行,取得行号即可。(get_location)
代码:
typedef std::vector<ptrdiff_t> offset_data_t;
bool build_offset_data(offset_data_t& result, const char* file)
{
FILE* f = fopen(file, "rb");
if (!f) return false;
ptrdiff_t offset = 0;
char buffer[1024];
size_t size;
while ((size = fread(buffer, 1, sizeof(buffer), f)) > 0)
{
for (size_t i = 0; i < size; ++i)
if (buffer[i] == '\n')
result.push_back(offset + i);
offset += size;
}
fclose(f);
return true;
}
std::pair<int, int> get_location(const offset_data_t& data, ptrdiff_t offset)
{
offset_data_t::const_iterator it = std::lower_bound(data.begin(), data.end(), offset);
size_t index = it - data.begin();
return std::make_pair(1 + index, index == 0 ? offset + 1 : offset - data[index - 1]);
}