Знает ли кто-нибудь, как заполнить таблицу в xml-шаблоне данными, передаваемыми из программы в виде массива? Я пока что нашёл только заполнение через sql-запрос и из текстового файла. Или такое вообще невозможно?
ncreport 0.7 (Таблицы)
Модератор: Модераторы разделов
-
begin2009
- Сообщения: 349
- Статус: Ламер со стажем
- ОС: без глюков
Re: ncreport 0.7
А ничего что на паскале? Я недавно подобное (если правильно понял условие) делал. Смысл моей проги чтение xml файла и запись в сетку StringGrid (у меня названа MaunGrid).
Процедура для парсинга и записи в сетку:
Используестя технология DOM. И надо подключать в uses модули DOM, xmlRead. Или не то?
Процедура для парсинга и записи в сетку:
Код: Выделить всё
procedure DumpNode(node: TDOMNode); // процедура для парсинга XML документа
var // и заполнения сетки
col: Integer; // номер колонки
sValue, field: string; // значение и имя тега в XML документе
begin
// Если имя тега "ROW" (в нем заключена запись),
// вставляется в сетку новая строка
field:=node.NodeName;
if field='ROW'
then MainForm.MainGrid.RowCount:=MainForm.MainGrid.RowCount+1;
// Если имя тега "SET", "HEAD", "PROC" "ORGAN"(название муниципального образования,
// ФИО Главы и инспектора по учету и бронированию военнообязанных исполнительный
// орган муниципального образования, юридический адрес, номер телефона, район и
// регион присваиваются соответствующим переменным.
if node.NodeName='STATUS' then
begin
if node.FirstChild=nil
then tipMO:=''
else tipMO:=node.FirstChild.NodeValue;
end;
if node.NodeName='SET' then
begin
if node.FirstChild=nil
then stlm:=''
else stlm:=node.FirstChild.NodeValue;
end;
if node.NodeName='ORGAN' then
begin
if node.FirstChild=nil
then organ:=''
else organ:=node.FirstChild.NodeValue;
end;
if field='HEAD' then
begin
if node.FirstChild=nil
then head:=''
else head:=node.FirstChild.NodeValue;
end;
if field='PROC' then
begin
if node.FirstChild=nil
then work:=''
else work:=node.FirstChild.NodeValue;
end;
if node.NodeName='DSTR' then
begin
if node.FirstChild=nil
then district:=''
else district:=node.FirstChild.NodeValue;
end;
if node.NodeName='REG' then
begin
if node.FirstChild=nil
then region:=''
else region:=node.FirstChild.NodeValue;
end;
if node.NodeName='URADR' then
begin
if node.FirstChild=nil
then addr:=''
else addr:=node.FirstChild.NodeValue;
end;
if node.NodeName='PHONE' then
begin
if node.FirstChild=nil
then phon:=''
else phon:=node.FirstChild.NodeValue;
end;
if node.NodeName='TOWN' then
begin
if node.FirstChild=nil
then towns:=''
else towns:=node.FirstChild.NodeValue;
end;
if node.NodeName='BOOK' then
begin
if node.FirstChild=nil
then book:=''
else book:=node.FirstChild.NodeValue;
end;
if node.NodeName='FBK' then
begin
if node.FirstChild=nil
then fabric:=''
else fabric:=node.FirstChild.NodeValue;
end;
// парсинг записи и заполнение сетки
if isTag(node.NodeName,col) // функция возвращает TRUE при обнаружении тега, а
// в переменную col записывает номер колонки сетки
then
begin
// у элементов верхнего уровня значений нет
if node.FirstChild=nil then sValue:=''
// читаются значения тега
else sValue:=node.FirstChild.NodeValue;
// в ячейку с номером колонки col в последней строке помещает значение тега
MainForm.MainGrid.Cells[col,MainForm.MainGrid.RowCount-1]:=sValue;
end;
if node.FirstChild <> nil then // если не последний уровень документа, рекурсивно
begin // разбирается нижний узел
DumpNode(node.FirstChild);
end;
if node.NextSibling <> nil then // если не конец документа
DumpNode(node.NextSibling); // разбирается следующая запись
end;Используестя технология DOM. И надо подключать в uses модули DOM, xmlRead. Или не то?
Пессимист видит темный туннель, оптимист видит свет в конце туннеля, реалист видит свет, туннель и поезд.
И только машинист видит этих трех идиотов, сидящих на рельсах.
И только машинист видит этих трех идиотов, сидящих на рельсах.
-
Obscurus
- Сообщения: 177
Re: ncreport 0.7
Боюсь, что это совсем не то
NCReport - это библиотека для Qt, предназначенная для подготовки и печати отчётов (ну и экспорта в разные форматы). В виде xml-файла задаётся шаблон и скармливается библиотеке, в самой программе ничего парсить не нужно. В большинстве случаев созданный шаблон уже содержит sql выражение, по результатам которого и рисуются разные таблицы. Я пытаюсь разобраться, можно ли передавать туда уже готовые наборы данных, без использования базы.
А DOM у меня почему-то ассоциируется с Web 2.0 ))
А DOM у меня почему-то ассоциируется с Web 2.0 ))
-
begin2009
- Сообщения: 349
- Статус: Ламер со стажем
- ОС: без глюков
Re: ncreport 0.7
А если парсить не взирая на ту библиотеку? Под си тоже есть DOM, правда я им не пользовался, но вот ссылка на обсуждение, может пригодится: http://www.rsdn.ru/forum/cpp.applied/1456451.flat.aspx
А сам DOM это не Web, а скорее JavaScript в нем.
А сам DOM это не Web, а скорее JavaScript в нем.
(Wiki) писал(а):DOM (от англ. Document Object Model — «объектная модель документа») — это не зависящий от платформы и языка программный интерфейс, позволяющий программам и скриптам получить доступ к содержимому HTML, XHTML и XML-документов, а также изменять содержимое, структуру и оформление таких документов.
Пессимист видит темный туннель, оптимист видит свет в конце туннеля, реалист видит свет, туннель и поезд.
И только машинист видит этих трех идиотов, сидящих на рельсах.
И только машинист видит этих трех идиотов, сидящих на рельсах.
-
Obscurus
- Сообщения: 177
Re: ncreport 0.7
Это уже хардкорный велосипед
- парсить самому, рисовать самому, в PDF экспортировать опять самому, а если на печать выводить, то и вовсе умучаешся. Не стоит оно того, по моему. Гораздо проще будет создавать временные файлы (например CSV) и их-то уже передавать шаблону.
-
NickLion
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: ncreport 0.7
Если Qt уже есть, то лучше использовать QtXml. Что-то вроде:
Полученный на выходе XML файл:
Для того, чтобы распарсить уже существующий достаточно:
Код: Выделить всё
#include <QtCore/QCoreApplication>
#include <QTextStream>
#include <QtXml>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QDomDocument doc;
doc.appendChild( doc.createProcessingInstruction( "xml", "version='1.0' encoding='utf-8'" ) );
doc.appendChild( doc.createElement( "root" ) );
QDomElement que = doc.createElement( "level1" );
QDomElement txe = doc.createElement( "level2" );
QDomText txt = doc.createTextNode( "Some text data" );
QDomElement txe2 = doc.createElement( "level2" );
txe2.setAttribute( "attr1", 37 );
txe2.setAttribute( "attr2", "ad sf sdfe" );
txe.appendChild( txt );
que.appendChild( txe );
que.appendChild( txe2 );
doc.documentElement().appendChild( que );
QFile file( "text.xml" );
file.open( QIODevice::WriteOnly );
QTextStream out( &file );
out << doc.toString( 4 );
file.close();
return 0; //a.exec();
}Полученный на выходе XML файл:
Код: Выделить всё
<?xml version='1.0' encoding='utf-8'?>
<root>
<level1>
<level2>Some text data</level2>
<level2 attr1="37" attr2="ad sf sdfe"/>
</level1>
</root>Для того, чтобы распарсить уже существующий достаточно:
Код: Выделить всё
QFile file( "text.xml" );
file.open( QIODevice::ReadOnly );
doc.setContent( &file );
file.close();