Что самый простой способ генерации 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, как указано выше. Он также сохранит файл в одной команде, но я не могу узнать, как сохранить его в буфере.