0

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

XMLPrinter 类似乎可以满足我的需要,但它不能正确打印文本。

我的 XML:

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

我的类扩展了 XMLPrinter 类:

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>and<i>元素之后的所有文本?我该如何解决这个问题?此外,XMLPrinter 类使用标签正确地打印出来,但我不想要标签。

4

1 回答 1

1

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

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

第一个问题是您正在修改XMLPrinter. 这派生自XMLVisitor并创建了 XML 文档的可打印表示。但是然后你用你自己的方法替换 allXMLPrintervisit...方法。直接派生出来会更好,工作量也更少XMLVisitor

其次,您将VisitEnter单独使用元素文本,GetText()当子节点嵌入其中时,它将不起作用,如此所述。

在这种情况下,要仅获取所有元素的文本,覆盖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;
}
于 2017-04-11T21:29:12.993 回答