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

时间:2017-04-11 18:22:31

标签: c++ tinyxml2

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

1 个答案:

答案 0 :(得分:1)

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

DECLARE @InputTable AS TABLE ( [Rank] INT IDENTITY(1,1), StudentId VARCHAR(1) ) INSERT INTO @InputTable (StudentId) SELECT StudentId FROM ( SELECT DISTINCT StudentId FROM MyTable --Could use your student table WHERE CHARINDEX(studentId + ',', @input + ',') > 0) x ORDER BY CHARINDEX(studentId + ',', @input + ',') SELECT SubjectId FROM MyTable t INNER JOIN @InputTable i ON t.[Rank] = i.[Rank] AND t.[StudentId] = i.[StudentId] GROUP BY SubjectId HAVING COUNT(* ) = (SELECT COUNT(* ) FROM @InputTable) AND COUNT(* ) = (SELECT COUNT(* ) FROM MyTable WHERE SubjectId = t.SubjectId) 派生自XMLPrinter,并以完整,标签,属性等方式打印XML文档(或元素)。 XMLVisitor执行在XML层次结构中上下递归的工作,调用默认值,不执行任何操作,方法XMLVisitor / VisitEnter的实现可用于可以具有子代(子项)的节点,即文档和叶子节点的元素和“访问”,即文本,注释等。在派生类中重写这些方法以实现所需的功能。

第一个问题是您正在修改VisitExit。这源自XMLPrinter并创建XML文档的可打印表示。但是,您可以用自己的方法替换所有XMLVisitor 访问... 方法。 XMLPrinter派生出来会更好,也更少工作。

其次,您使用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;
}