Я использую инструмент CodeSynthesis XSD для генерации XML-файла в соответствии с заданным XSD-файлом. Я знаю, что можно построить дерево XML и сериализовать его в поток. Но мой вопрос:
Можно ли сгенерировать элементы XML один за другим?
Предположим, я хочу создать <root>
элемент, который содержит <element1>
а также <element2>
, Теперь я могу только построить <root>
дерево и сериализовать его одним куском. Что я хочу это:
Первый генерировать <root>
, затем <element1>...</element1>
а также <element2>...</element2>
, в конце концов </root>
,
Поскольку синтаксический анализатор поддерживает обратные вызовы, легко получить контроль над каждым узлом сразу после того, как узел становится доступным. Возможно ли это для картирования деревьев?
Я копаю документацию, но не нашел правильного ответа. Я буду признателен за любую возможную помощь или подсказки. Заранее спасибо 🙂
— Редактировать —
Чтобы было понятно: во-первых, исходные XML-данные генерируются моей программой (не из существующего XML-файла); Во-вторых, я хочу сериализовать объект XML сразу после его создания вместо сериализации всего дерева.
Я знаю цели XSD / Tree при обработке в виде дерева в памяти, но мне интересно, можно ли писать как xxx_open
а также xxx_close
и т.п.
Еще раз спасибо.
Да, возможно генерировать элементы один за другим с помощью CodeSynthesis XSD. Например, это
пример потоковой передачи
генерирует этот файл XML:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<op:object xmlns:op="http://www.codesynthesis.com/op" id="123" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.codesynthesis.com/op position.xsd">
<header>
<name>Lion's Head</name>
<type>rock</type>
</header>
<position lat="-33.8569" lon="18.5083"/>
<position lat="-33.8568" lon="18.5083"/>
<position lat="-33.8568" lon="18.5082"/>
<position lat="-33.857" lon="18.5083"/>
<position lat="-33.8569" lon="18.5084"/>
<position lat="-33.857" lon="18.5084"/>
<position lat="-33.857" lon="18.5082"/>
<position lat="-33.8569" lon="18.5082"/>
</op:object>
В файле driver.cxx каждый элемент позиции генерируется путем вызова
s.next ("position", pos);
Чтобы иметь больше контроля над тем, какие префиксы пространства имен будут использоваться в выходных данных, вы можете использовать эту функцию вместо этого из файла serializer.hxx
// Serialize next object model fragment into an element with the specified
// namespace and qualified name as well as namespace declarations.
//
template <typename T>
void
next (const std::string& ns,
const std::string& name,
const namespace_infomap&,
const T& x);
В файле driver.cxx объект позиции создается из дерева XML DOM
position pos (*doc1->getDocumentElement ());
так что именно этот конструктор используется:
position (const ::xercesc::DOMElement& e,
::xml_schema::flags f = 0,
::xml_schema::container* c = 0);
это можно увидеть в сгенерированном файле position.hxx.
Но вы упоминаете, что вы создаете свои объекты из не-XML источника, поэтому вам вместо этого нужно будет использовать конструктор, который принимает значения элементов в качестве входных данных:
position (const lat_type&,
const lon_type&);