如何在pugixml中获取节点的内部XML

How to get inner XML of a node in pugixml?

本文关键字:节点 内部 XML 获取 pugixml      更新时间:2023-10-16

我解析一个文档,并希望以字符串的形式检索XML树的一部分。文件(示例(:

<?xml version="1.0"?>
<MyConfig>
<MyData>
<Foo bar="baz>42</Foo>
</MyData>
<OtherData>Something</OtherData>
</MyConfig>

代码:

pugi::xml_document doc;
doc.load_file(documentFileName);
pugi::xml_node root = doc.child("MyConfig");
// parse custom data
_customData = root.child("MyData"). <-- HOW TO GET INNER XML?

自定义数据的预期内容(如果格式丢失,我不介意(:

"<Foo bar="baz>42</Foo>"

如何做到这一点?

我直接在文档中找到了一个解决方案,只是谷歌没有很好地索引它们,所以我不得不手动查找。我的解决方案是使用pugi::xml_writernode.print。在文档中,他们甚至已经展示了std::string:的实现

struct xml_string_writer: pugi::xml_writer
{
std::string result;
virtual void write(const void* data, size_t size)
{
result.append(static_cast<const char*>(data), size);
}
};

有了它,我只做了一个方便的函数来合并所有子节点的XML:

std::string InnerXML(pugi::xml_node target)
{
xml_string_writer writer;
for (pugi::xml_node child = target.first_child(); child; child = child.next_sibling())
child.print(writer, "");
return writer.result;
}

我认为pugi::xml_node::print()是一种方式。

pugi::xml_node node = root.child("MyData");
pugi::xml_node child = node.first_child();
std::stringstream ss;
child.print(ss);
std::string s = ss.str();

问题是s现在将具有值

<Foo bar="baz&gt;42&lt;/Foo&gt;     &lt;/MyData&gt;     &lt;OtherData&gt;Something&lt;/OtherData&gt; &gt; &#10;&lt;/MyConfig&gt;" />
  1. 这是从节点开始的文本树,并且
  2. html转义序列而不是<>会很混乱

并不理想,但这些问题显然可以通过一些字符串操作来解决。

// replace &lt; with <
size_t off = 0;
while ((off = s.find("&lt;", off)) != s.npos)
s.replace(off, 4, "<");
// replace &gt; with >
off = 0;
while ((off = s.find("&gt;", off)) != s.npos)
s.replace(off, 4, ">");
// truncate at the closing tag
size_t end_open = s.find(">", 0);
size_t end_close = s.find(">", end_open + 1);
s = s.substr(0, end_close + 1);

这将导致s具有值

<Foo bar="baz>42</Foo>