Работа с XML

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
ziceptor
незнакомец
Сообщения: 6
Зарегистрирован: 22.03.2015 17:04:17

Работа с XML

Сообщение ziceptor »

Работаю штатными средствами (DOM, XMLRead, XMLWrite). Загрузка, поиск и обращение к нодам и просмотр их значений не представляет сложности. Допустим есть XML документ:

Код: Выделить всё

<?xml version="1.0" encoding="UTF-8"?>
<ttt>
  <sss>000</sss>
  <tit>1</tit>
  <Q1>
    <tim>13</tim>
    <A1>
      <S>se1</S>
      <T>te1</T>
    </A1>
    <A2>
      <S>se1</S>
      <T>te2</T>
    </A2>
  </Q1>
    ....
</ttt>


Как вывести, к примеру в memo часть XML документа? Есть встроенный механизм вывода куста?

Код: Выделить всё

    <A1>
      <S>se1</S>
      <T>te1</T>
    </A1>
wavebvg
постоялец
Сообщения: 355
Зарегистрирован: 28.02.2008 03:57:35

Сообщение wavebvg »

XPath Вам в руки :-)
ziceptor
незнакомец
Сообщения: 6
Зарегистрирован: 22.03.2015 17:04:17

Сообщение ziceptor »

wavebvg Вы пробовали с его помощью выполнить поставленную задачу? Функция AsText отдаёт голый текст.. без тегов. То же самое я могу сделать без использования XPath. Или я не туда смотрю и не то делаю?
wavebvg
постоялец
Сообщения: 355
Зарегистрирован: 28.02.2008 03:57:35

Сообщение wavebvg »

Вы можете всё сделать вручную.
Если задачу нужно делать один раз в абстрактном вакууме со сверическими данными - то можно ручками:
1. Пропускаем до /ttt/Q1/A1
2. Читаем и записываем в строку до /ttt/Q1
3. Выводим строку в Memo

Или вопрос заключается в следующем: как вывести из читалки сформированный XML? Это просто берем XMLWrite и кормим ей теги, которые нашли во время чтения.

Так же упоминание читалки и писалки предполагает, что Вы хотите воспользоваться именно или другие варианты Вам не интересны?

В любом случае можно посмотреть тут http://wiki.lazarus.freepascal.org/XML_Tutorial/ru
Решаются похожие задачи с предварительным парсингом документа.
ziceptor
незнакомец
Сообщения: 6
Зарегистрирован: 22.03.2015 17:04:17

Сообщение ziceptor »

wavebvg Я читал документацию. Вопрос заключается в
ziceptor писал(а):Как вывести, к примеру в memo часть XML документа? Есть встроенный механизм вывода куста?
К примеру, в simplexml куст можно получить так: XMLdoc.DocumentElement.SelectSingleNode('Q1').XML
Судя по исходникам, в lazarus эту задачу решать надо самостоятельно.
sign
энтузиаст
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53

Сообщение sign »

ziceptor писал(а):Как вывести, к примеру в memo часть XML документа? Есть встроенный механизм вывода куста?

Пара минут стучания по клавиатуре, беря в голову вот эту возможность... и всё.

Код: Выделить всё

var L: TStringList;
begin
  L.LoadFromFile('');
...
end;
ziceptor
незнакомец
Сообщения: 6
Зарегистрирован: 22.03.2015 17:04:17

Сообщение ziceptor »

sign
ziceptor писал(а):Работаю штатными средствами (DOM, XMLRead, XMLWrite).
Зачем грузить файл в StringList и городить свой огород, если все данные можно получить штатными средствами.. достаточно написать свою функцию, что и сделал.
wavebvg
постоялец
Сообщения: 355
Зарегистрирован: 28.02.2008 03:57:35

Сообщение wavebvg »

Код: Выделить всё

procedure TForm1.Button1Click(Sender: TObject);
var
  Q1: TDOMNode;
  Doc:      TXMLDocument;
  Data: TStringStream;
begin
  Data := TStringStream.Create(MemoData.Lines.Text);
  try
     ReadXMLFile(Doc, Data);
  finally
    Data.Free;;
  end;
  Q1 := Doc.DocumentElement.FindNode('Q1');
  Data := TStringStream.Create('');
  try
     WriteXML(Q1, Data);
     MemoResult.Lines.Text := Data.DataString;
  finally
    Data.Free;;
  end;
end;
ziceptor
незнакомец
Сообщения: 6
Зарегистрирован: 22.03.2015 17:04:17

Сообщение ziceptor »

Я сделал через циклы, так как нужен еще контроль значений, но это уже сугубо потребности проекта. Для решения же заданного вопроса, как вариант, можно сделать так, как предложил wavebvg.

Вопрос закрыт.

p.s. Для Delphi рекомендую работать с xml при помощи замечательного бесплатного, во всех отношениях, simplexml от Михаила Власова, замечательный модуль. Несколько лет назад мы вели переписку... он перешел на C# и забросил проект, но за все годы использования глюков не было. В связи с выходом новых версий Delphi, Краснов Кирилл добавил поддержку юникода, выложил код на https://github.com/Kirill/simplexml. Модуль подробно документирован (и в коде и в chm формате). Если есть у кого-нибудь желание, то можете портировать под Lazarus/FPC.
wavebvg
постоялец
Сообщения: 355
Зарегистрирован: 28.02.2008 03:57:35

Сообщение wavebvg »

ziceptor писал(а):Если есть у кого-нибудь желание, то можете портировать под Lazarus/FPC.

Под FPC, помимо вошедших в поставку (1), есть ещё NativeXML (2) (быстро, просто, понятно, нет излишеств, никаких ненужных наворотов).
Для особо "ленивых" можно воспользоваться libxml2 (3) - там множество фишек, типо парсинга, валидации, работы с деревом, шаблоны, свой http клиент...
ziceptor
незнакомец
Сообщения: 6
Зарегистрирован: 22.03.2015 17:04:17

Сообщение ziceptor »

wavebvg писал(а):Под FPC, помимо вошедших

Я знаю, что есть. Это ведь не означает, что не появится еще. ;) Просто указал, для сравнения, что есть такой-то модуль.
Ustas
постоялец
Сообщения: 153
Зарегистрирован: 19.10.2009 14:58:10
Откуда: г.Муром

Сообщение Ustas »

Вопрос по теме, но о другом (сори у автора темы).
Делаю второй шаг в XML и столкнулся вот с чем:

Windows 7, Lasarus 1.6, использую XMLRead, XMLWrite, DOM.
При добавление элемента, используя TXMLDocument.CreateElement и TXMLDocument.GetElementsByTagName происходит объединение/смешивание веток с существующей веткой с таким же именем, хотя эти ветки должны быть на разных элементах и/или разных уровнях.
Как мне строить конкретно выбранную ветку?
Ответить