TinyXML2 从节点和所有子节点获取文本

TinyXML2 get text from node and all subnodes

如何从 TinyXML2 中的节点和子节点获取文本?

XML打印机 class 似乎可以满足我的需要,但它无法正确打印文本。

我的XML:

<div>The quick brown <b>fox</b> jumps over the <i>lazy</i> dog.</div>

My class 扩展了 XMLPrinter class:

class XMLTextPrinter : public XMLPrinter {
    virtual bool    VisitEnter (const XMLDocument &) { return true; }
    virtual bool    VisitExit (const XMLDocument &)  { return true; }
    virtual bool    VisitEnter (const XMLElement &e, const XMLAttribute *)  {
        auto text = e.GetText();
        if(text) {
            std::cout << text;
        }
        return true;
    }
    virtual bool    VisitExit (const XMLElement &e)  { return true; }
    virtual bool    Visit (const XMLDeclaration &)  { return true; }
    virtual bool    Visit (const XMLText &e) { return true; }
    virtual bool    Visit (const XMLComment &)  { return true; }
    virtual bool    Visit (const XMLUnknown &)  { return true; }
};

我的代码:

XMLDocument document;
document.Parse(..., ...);

auto elem = ...;

XMLTextPrinter printer;
elem->Accept(&printer);

输出:

The quick brown foxlazy

为什么忽略 <b><i> 元素之后的所有文本?我该如何解决这个问题?此外,XML打印机 class 正确打印出来 带有 标签,但我不想要标签。

[2017 年 4 月 14 日编辑以改进(我希望)]

XMLPrinter 派生自 XMLVisitor 并完整打印 XML 文档(或元素)、标签、属性和所有内容。 XMLVisitor 执行在 XML 层次结构中上下递归的工作,调用默认值,什么也不做,为可以有后代(子节点)的节点实现方法 VisitEnter/VisitExit ,即文档和元素以及叶节点的“访问”,即文本、注释等。在派生的 class 中覆盖这些方法以实现所需的功能。

第一个问题是你在修改XMLPrinter。这源自 XMLVisitor 并创建 XML 文档的可打印表示。但是随后您将所有 XMLPrintervisit... 方法替换为您自己的方法。直接从 XMLVisitor 派生会更好,而且工作更少。

其次,您使用 GetText() 单独从 VisitEnter 获取元素文本,当子节点嵌入其中时将不起作用 as documented here.

在这种情况下,要仅获取所有元素的文本覆盖文本叶节点的 Visit,即 Visit(const XMLText &)

#include "tinyxml2.h"
#include <iostream>

using namespace tinyxml2;

class XMLPrintText : public XMLVisitor
{
public:
   virtual bool Visit (const XMLText & txt) override
   {
      std::cout << txt .Value();
      return true;
   }
};

int main()
{
   XMLDocument doc;
   doc.Parse ("<div>The quick brown <b>fox</b> jumps over the <i>lazy</i> dog.</div>");
   auto div = doc .FirstChildElement();
   XMLPrintText prt;
   div -> Accept (&prt);
   return 0;
}