0

如何在 TinyXML2 中迭代节点?我尝试按照文档进行操作,但无法掌握这一点。

http://www.grinninglizard.com/tinyxml2docs/index.html

我的 XML 已经加载到std::string. 因此,以下编译:

#include "tinyxml2.hpp"
// assume I have code here which reads my XML into std::string sXML
tinyxml2::XMLDocument doc;
doc.Parse( sXML.c_str() );

现在我该怎么做doc来迭代项目列表,以便我可以将里面的标题和作者字段提取到std::string变量中?

这是我的 XML 示例:

<?xml version=“1.0” encoding=“utf-8”?>
<books>
    <item>
        <title>Letters to Gerhardt</title>
        <author>Von Strudel, Jamath</author>
    </item>
    <item>
        <title>Swiss Systemic Cleanliness Principles, The</title>
        <author>Jöhansen, Jahnnes</author>
    </item>
</books>

希望有一些简单的东西,比如 C++ vectorof item,然后可能是 C++map里面我可以通过"title"and"author".titleor来解决它.author

4

3 回答 3

1

以下是一些您可能会发现有用的正在进行的工作:tinyxml2 扩展。文档不完整,因此您需要从测试示例中推断,直到完成。

您可以使用以下方式从 xml 中读取数据:

#include <iostream>
#include <tixml2ex.h>

auto doc = tinyxml2::load_document (sXML);
for (auto item : selection (*doc, "books/item"))
{
    std::cout << "title  : " << text (find_element (item, "title")) << std::endl;
    std::cout << "author : " << text (find_element (item, "author")) << std::endl << std::endl;
}

NB 真的应该被包裹在一个 try/catch 块中。

如果要将元素名称和属性存储为矢量和地图的某种组合,则必须根据需要进行复制。

于 2016-08-27T00:53:04.547 回答
1

可能最好的方法是实现一个XMLVisitor类(http://grinninglizard.com/tinyxml2docs/classtinyxml2_1_1_x_m_l_visitor.html)并使用该XMLNode::Accept()方法。然后在你的回调中,你可以获取你想要的字符串。

于 2016-12-15T01:29:43.363 回答
0
// PARSE BOOKS

#pragma once
#include <string>
#include <stdio.h>
#include <vector>
#include "tinyxml2.hpp"

struct myRec {
  std::string title;
  std::string author;
};

std::vector<myRec> recs;

tinyxml2::XMLDocument doc;
doc.Parse( sXML.c_str() );
tinyxml2::XMLElement* parent = doc.FirstChildElement("books");

tinyxml2::XMLElement *row = parent->FirstChildElement();
while (row != NULL) {
  tinyxml2::XMLElement *col = row->FirstChildElement();
  myRec rec;
  while (col != NULL) {
    std::string sKey;
    std::string sVal;
    char *sTemp1 = (char *)col->Value();
    if (sTemp1 != NULL) {
      sKey = static_cast<std::string>(sTemp1);
    } else {
      sKey = "";
    }
    char *sTemp2 = (char *)col->GetText();
    if (sTemp2 != NULL) {
      sVal = static_cast<std::string>(sTemp2);
    } else {
      sVal = "";
    }
    if (sKey == "title") {
      rec.title = sVal;
    }
    if (sKey == "author") {
      rec.author = sVal;
    }
    col = col->NextSiblingElement();
  } // end while col
  recs.push_back(rec);
  row = row->NextSiblingElement();
} // end while row
signed long nLen = recs.size();
if (nLen > 0) {
  --nLen;
  nLen = (nLen < 0) ? 0 : nLen;
  for (int i = 0; i <= nLen; i++) {
    std::string sTitle = recs[i].title;
    std::string sAuthor = recs[i].author;
    std::cout << sTitle << "\n" << sAuthor << "\n";
  }
} else {
  std::cout << "Empty rowset of books.\n";
}

请注意,我对 C++ 相当陌生。如果你知道用更少的行数优化它的方法,我会很高兴看到它。

于 2016-02-15T15:05:21.853 回答