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 文档的可打印表示。但是随后您将所有 XMLPrinter
的 visit... 方法替换为您自己的方法。直接从 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;
}
如何从 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 文档的可打印表示。但是随后您将所有 XMLPrinter
的 visit... 方法替换为您自己的方法。直接从 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;
}