2016-02-15 3 views
0

Как выполнить итерацию узлов в TinyXML2? Я пробовал следовать документации, но не могу это понять.Как перевести XML-узлы в C++ с помощью библиотеки 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> 

Надеялся что-то простое, как С ++ vector из item, а затем, возможно, C++ map внутри, где я могу адресовать его на "title" и "author" или .title или .author.

ответ

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++. Если вы знаете, как оптимизировать это в меньших количествах, я был бы в восторге от этого.

0

Проделайте следующие действия, которые могут оказаться полезными: tinyxml2 extension. Документация неполна, поэтому вам нужно будет вывести из тестового примера, пока он не будет завершен.

Вы можете прочитать данные из 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; 
} 

нотабене должен действительно быть завернут в блок try/catch.

Если вы хотите сохранить имена и атрибуты элементов как некоторую комбинацию вектора и карты, вам придется копировать по мере необходимости.

 Смежные вопросы

  • Нет связанных вопросов^_^