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

How to get inner XML of a node in pugixml?

我解析了一个文档并希望将 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_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 转义序列比 <>
  3. 更乱

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

// 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>

我找到了解决方案directly in the docs,只是google没有很好地索引它们,所以我不得不手动查找。我的解决方案是使用 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;
}