C++ RapidXML — редактирование значений в файле XML

Недавно я начал использовать RapidXML, и синтаксический анализ значений в порядке (я могу получить данные из элементов), но я хочу отредактировать значения внутри элементов.

Для целей этой программы я хочу повернуть это:

<?xml version="1.0" encoding="UTF-8"?>
<root>
     <data>
          This is data.
     </data>
</root>

В это:

<?xml version="1.0" encoding="UTF-8"?>
<root>
     <data>
          Edited!
     </data>
</root>

Я где-то читал, что у rapidxml::xml_node есть функция value() для изменения значения внутри элемента, но, похоже, она не работает. Когда я записываю в файл, я получаю то же самое, что и раньше. Вот мой код:

std::string input_xml = loadFile(filename);
std::vector<char> xml_copy(input_xml.begin(), input_xml.end());
xml_copy.push_back('\0');

rapidxml::xml_document<> doc;

doc.parse<rapidxml::parse_declaration_node | rapidxml::parse_non_destructive>(&xml_copy[0]);
// Also tried with doc.parse<0>(&xml_copy[0]) but no luck

rapidxml::xml_node<>* root_node = doc.first_node("root");

root_node->first_node("data")->value(std::string("Edited!").c_str());

std::string data = std::string(xml_copy.begin(), xml_copy.end());

std::ofstream file;
file.open(filename.c_str());
file << data;
file.close();

Любые идеи?


Изменить:

В сочетании с принятым ответом функция parse() также должна иметь флаг rapidxml::parse_no_data_nodes:

std::string input_xml = TileManager::getData(filename);
std::vector<char> xml_copy(input_xml.begin(), input_xml.end());
xml_copy.push_back('\0');

rapidxml::xml_document<> doc;

doc.parse<rapidxml::parse_no_data_nodes>(&xml_copy[0]); // Notice the flag here
rapidxml::xml_node<>* root_node = doc.first_node("root");

std::string s = "test";
const char * text = doc.allocate_string(s.c_str(), strlen(s.c_str()));

root_node->first_node("data")->value(text);

std::string data;
rapidxml::print(std::back_inserter(data), doc);

std::ofstream file;
file.open(filename.c_str());
file << data;
file.close();

Тогда это сработает.


person Community    schedule 24.02.2013    source источник
comment
Каким должен быть loadFile()?   -  person FriskySaga    schedule 08.07.2020


Ответы (2)


Взгляните на этот http://rapidxml.sourceforge.net/manual.html#namespacerapidxml_1lifetime_of_source_text. При работе с RapidXML вы в основном должны гарантировать, что любые строки, которые вы записываете в документ, сохраняются на протяжении всего срока действия документа. В вашем коде вы назначаете временное значение, которого не будет после этого вызова.

root_node->first_node("data")->value(std::string("Edited!").c_str());

пытаться

std::string new_value = "Edited!";
root_node->first_node("data")->value(new_value.c_str());

и это должно работать для вас. Взгляните на это также в отношении вывода результирующего XML в строку http://rapidxml.sourceforge.net/manual.html#namespacerapidxml_1printing

person mathematician1975    schedule 24.02.2013
comment
Понятно. Обновил вопрос. - person ; 25.02.2013

флаг синтаксического анализа rapidxml::parse_no_data_nodes недостаточен. Отсутствует узел объявления

‹ ?xml версия="1.0" кодировка="UTF-8"? >

в выходном файле.

Вы должны использовать, например, похожие флаги:

 doc.parse < trapidxml::parse_full | rapidxml::parse_no_data_nodes >(&xml_copy[0]);

Тогда это работает. [ЦентОС7.2]

person user2915531    schedule 02.04.2016