Что самый простой способ генерации xml в С++?
Я использовал форсированную сериализацию, но это, похоже, не позволяет мне генерировать xml, который соответствует конкретной схеме - кажется, что цель состояла в том, чтобы просто сохранить состояние класса.
Платформа: linux
Что вы, ребята, используете для генерации NOT parse xml?
До сих пор я иду по пути Foredecker, просто создавая его сам - это не большой документ, но мне действительно не должно быть так много проблем с поиском приличной библиотеки, чтобы сгенерировать его правильно.
Что касается boost, то, что я хотел бы сделать, это установить имена node, установить атрибуты в моих узлах и избавиться от всего лишнего дерьма, которое приходит с ним, поскольку я действительно не заботиться о том, чтобы вернуть мой документ в этот класс.
Ответы
Ответ 1
Некоторые могут объявить меня еретиком XML, но один эффективный способ - просто сгенерировать его с помощью ваших любимых инструментов вывода строк (печать, выходные потоки и т.д.) - это может перейти в буфер или файл.
После сохранения - вы действительно должны затем выполнить проверку со схемой, прежде чем совершать ее, чтобы отгрузить ее.
Для одного из наших проектов у нас есть очень простой набор шаблонов для управления тегами и атрибутами начала и конца. Каждый из них имеет оператор вывода потока. Это позволяет легко генерировать исходный XML и отлаживать. Это делает структуру кода генерации XML очень похожей на сам XML.
Одно из преимуществ этого заключается в том, что вы можете эффективно генерировать большие объемы XML, если потоковая передача в файл. Вы оплатите стоимость проверки позже (предположительно, в более выгодное время для дорогостоящей операции).
Недостатком этого метода является то, что он по сути является выходным. Он не подходит для создания динамического потребления XML.
Ответ 2
Недавно я рассмотрел кучу XML-библиотек специально для генерации XML-кода.
Резюме: Я решил пойти с TinyXML ++.
TinyXML ++ имеет приличный синтаксис С++, встроен в зрелые библиотеки TinyXML C, является бесплатным и открытым исходным кодом (лицензия MIT) и маленький. Короче говоря, это помогает быстро выполнить задание. Вот быстрый фрагмент:
Document doc;
Node* root(doc.InsertEndChild(Element("RootNode")));
Element measurements("measurements");
Element tbr("TotalBytesReceived", 12);
measurements.InsertEndChild(tbr);
root->InsertEndChild(measurements);
Что производит:
<RootNode>
<measurements>
<TotalBytesReceived>12</TotalBytesReceived>
</measurements>
</RootNode>
Я был очень доволен этим.
Я рассмотрел многие другие; вот некоторые из лучших претендентов:
Xerces: Король-папа. Делает все (особенно в сочетании с Xalan), но имеет супертяжелый вес и принудительно управляет памятью пользователя.
RapidXML: отлично подходит для синтаксического анализа (это синтаксический анализатор in-situ и работает быстро), но не подходит для генерации с момента добавления узлов в DOM требует управления памятью.
Boost.XML (предложение): Выглядит отлично - мощный, отличный синтаксис С++. Однако он еще не прошел процесс обзора, не поддерживается и интерфейс может измениться. В любом случае, он почти всегда использовался. Ждем его принятия в Boost.
Libxml (++): Очень хорошо; мощный, достойный синтаксис. Но это большое, если все, что вы делаете, генерирует XML и привязывается к библиотеке glibmm (для ustring). Если бы мы были только на Linux (как и вы?), Я бы серьезно подумал.
XiMOL: уникальная потоковая библиотека. Это было слишком упрощенным для наших нужд, но для создания основного XML вы можете найти его весьма полезным. Синтаксис потока довольно опрятный.
Надеюсь, там что-то есть!
Ответ 3
Boost.PropertyTree - это хороший и простой способ генерации XML - особенно если вы уже используете Boost.
Ниже приведена полная примерная программа:
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
using boost::property_tree::ptree;
using boost::property_tree::write_xml;
using boost::property_tree::xml_writer_settings;
int wmain(int argc, wchar_t* argv[]) {
char* titles[] = {"And Then There Were None", "Android Games", "The Lord of the Rings"};
ptree tree;
tree.add("library.<xmlattr>.version", "1.0");
for (int i = 0; i < 3; i++) {
ptree& book = tree.add("library.books.book", "");
book.add("title", titles[i]);
book.add("<xmlattr>.id", i);
book.add("pageCount", (i+1) * 234);
}
// Note that starting with Boost 1.56, the template argument must be std::string
// instead of char
write_xml("C:\\Users\\Daniel\\Desktop\\test.xml", tree,
std::locale(),
xml_writer_settings<char>(' ', 4));
return 0;
}
Полученный XML выглядит следующим образом:
<?xml version="1.0" encoding="utf-8"?>
<library version="1.0">
<books>
<book id="0">
<title>And Then There Were None</title>
<pageCount>234</pageCount>
</book>
<book id="1">
<title>Android Games</title>
<pageCount>468</pageCount>
</book>
<book id="2">
<title>The Lord of the Rings</title>
<pageCount>702</pageCount>
</book>
</books>
</library>
Одна вещь, которая особенно хороша, - это пути, разделенные точками, которые позволяют вам неявно создавать все узлы на этом пути. Документация довольно скудная, но вместе с ptree.hpp
должна дать вам представление о том, как она работает.
Ответ 4
Какая платформа?
MSXML - это опция в Windows.
CMarkup - еще один хороший выбор.
Если .NET является вариантом, он имеет отличную поддержку XML.
Ответ 5
Я действительно не пробовал сделать сериализацию, чтобы сделать это, но, насколько я понимаю, если вы очень тщательно подбираете свои параметры, вы можете установить множество схем в схеме (например, предотвращать укладку указателя и устанавливать имена элементов для определенных типов)
Ответ 6
Я использую tinyXml ++, и это упрощает создание xml, как указано выше. Он также сохранит файл в одной команде, но я не могу узнать, как сохранить его в буфере.