Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.03.2011, 15:36   #1
aspire89
 
Регистрация: 27.03.2011
Сообщений: 4
По умолчанию Разбор сложного xml файла

Прошу помощи.
Есть xml файл вида:
Код HTML:
<?xml version="1.0"?>
<DeviceProfile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Serial>24767</Serial>
  <Id>0</Id>
  <TerminalSerial>24767</TerminalSerial>
  <AnalogSensors>
    <AnalogSensor>
      <Name>Топливо</Name>
      <UnitText>л.</UnitText>
      <Enabled>true</Enabled>
      <AIN>0</AIN>
      <CalibrationPoints>
        <CalibrationPoint>
          <InputValue>0</InputValue>
          <OutputValue>880</OutputValue>
        </CalibrationPoint>
        <CalibrationPoint>
          <InputValue>21</InputValue>
          <OutputValue>550</OutputValue>
        </CalibrationPoint>
        <CalibrationPoint>
          <InputValue>25</InputValue>
          <OutputValue>500</OutputValue>
        </CalibrationPoint>
        <CalibrationPoint>
          <InputValue>42</InputValue>
          <OutputValue>450</OutputValue>
        </CalibrationPoint>
        <CalibrationPoint>
          <InputValue>59</InputValue>
          <OutputValue>400</OutputValue>
        </CalibrationPoint>
        <CalibrationPoint>
          <InputValue>76</InputValue>
          <OutputValue>350</OutputValue>
        </CalibrationPoint>
        <CalibrationPoint>
          <InputValue>90</InputValue>
          <OutputValue>300</OutputValue>
        </CalibrationPoint>
      </CalibrationPoints>
      <DI_Number>0</DI_Number>
      <FilterLength>20</FilterLength>
    </AnalogSensor>
    <AnalogSensor>
      <Name>Аналоговый вход 1</Name>
      <UnitText />
      <Enabled>false</Enabled>
      <AIN>1</AIN>
      <CalibrationPoints>
        <CalibrationPoint>
          <InputValue>0</InputValue>
          <OutputValue>0</OutputValue>
        </CalibrationPoint>
        <CalibrationPoint>
          <InputValue>1023</InputValue>
          <OutputValue>1023</OutputValue>
        </CalibrationPoint>
      </CalibrationPoints>
      <DI_Number>0</DI_Number>
      <FilterLength>20</FilterLength>
    </AnalogSensor>
....
Загрузку всех AnalogSensor в ListBox сделал следующим образом:
Код:
var
  i:integer;
begin
  CheckListBox1.Clear;
  _xml:=TXMLDocument.Create(self);
  if not FileOpenDialog1.Execute then Exit;
  XmlPath:=FileOpenDialog1.FileName;
  _xml.LoadFromFile(XmlPath);
  _xml.Active:=true;

  StatusBar1.Panels[0].Text:='Терминал: '+_xml.DocumentElement.ChildNodes.Nodes['TerminalSerial'].NodeValue;
  with _xml.DocumentElement.ChildNodes['AnalogSensors'] do
  begin
    if not (ChildNodes.FindNode('AnalogSensor')=nil) then
    begin
      for i:=0 to ChildNodes.Count-1 do
        if ChildNodes[i].NodeName='AnalogSensor' then
        begin
          if not (ChildNodes.Nodes[i].ChildNodes['Name']=nil) then
          CheckListBox1.Items.Add(ChildNodes.Nodes[i].ChildNodes['Name'].NodeValue);
          if not (ChildNodes.Nodes[i].ChildNodes['Enabled']=nil) then
          begin
            if ChildNodes.Nodes[i].ChildNodes['Enabled'].NodeValue=True then CheckListBox1.Checked[i]:=true;
          end;
        end;
    end;
  end;
  _xml.Free;
Столкнулся с трудностью, нужно при двойном клике по ListBox загружать соответствующие значения CalibrationPoint в StringGrid. Вот, что написал:
Код:
var
  i,j:integer;
  s: widechar;
begin
  i:=CheckListBox1.ItemIndex;
  _xml:=TXMLDocument.Create(self);
  _xml.LoadFromFile(XmlPath);
  _xml.Active:=true;

  with _xml.DocumentElement.ChildNodes['AnalogSensors'] do
  begin
    if not (ChildNodes.FindNode('AnalogSensor')=nil) then
    begin
        if ChildNodes[i].NodeName='AnalogSensor' then
        begin
          with _xml.DocumentElement.ChildNodes['CalibrationPoints'] do
          begin
            //if not (ChildNodes.FindNode('CalibrationPoint')=nil) then
            begin
              for j:=0 to ChildNodes.Count-1 do
              begin
                  //if ChildNodes[i].NodeName='CalibrationPoint' then
                  //with _xml.DocumentElement.ChildNodes['CalibrationPoint'] do
                  begin
                    if not (ChildNodes.Nodes[j].ChildNodes['InputValue']=nil) then
                      StringGrid1.Cells[1,j]:=ChildNodes.Nodes[j].ChildNodes['InputValue'].NodeValue;
                    if not (ChildNodes.Nodes[i].ChildNodes['OutputValue']=nil) then
                      StringGrid1.Cells[2,j]:=ChildNodes.Nodes[j].ChildNodes['OutputValue'].NodeValue;
                  end;
              end;
            end;
          end;
        end;
    end;

  end;
  _xml.free;
В ответ получаю Could not convert variant of type Null into type OleStr.
Подскажите, что я делаю не так и что можно почитать по разбору xml.
aspire89 вне форума Ответить с цитированием
Старый 27.03.2011, 18:12   #2
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,527
По умолчанию

твой пример работал без ошибок но не показывал ничего (Delphi 7)
вот мой смотри
держи код (он стал короче).
Зачем каждый раз (при каждом клике) заниматься полной разборкой XML. Гораздо проще хранить разобранный и разбирать дополнительно только нужный кусочек.
Изображения
Тип файла: jpg 1.JPG (25.0 Кб, 255 просмотров)
Вложения
Тип файла: zip ч.zip (4.4 Кб, 54 просмотров)
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 27.03.2011 в 18:16.
evg_m вне форума Ответить с цитированием
Старый 27.03.2011, 19:37   #3
aspire89
 
Регистрация: 27.03.2011
Сообщений: 4
По умолчанию

Спасибо, понял как работать с xml. Переписал ваш код на место своего, все компилируется. При открытии xml файла Name из AnalogSensor добавляются на ListBox, но при клике на по любой строке появляется ошибка:

Delphi XE
aspire89 вне форума Ответить с цитированием
Старый 27.03.2011, 22:07   #4
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,527
По умолчанию

DelphiXЕ увы нет.
не видя кода сказать что-то определенное трудно.
проверьте на всякий случай. может вы случайно после заполнения Listbox сделали (оставили от предыдущего варианта).
_xml.active:=false;
_xml.Free;
этого делать не надо. файл должен быть открыт постоянно. А переменную _xml лучше сделать полем класса.
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 27.03.2011, 22:15   #5
aspire89
 
Регистрация: 27.03.2011
Сообщений: 4
По умолчанию

Пробовал ваш проект запускал из архива и аналогичная ошибка.
Комментировал с конца до последней строчки и выяснил, что ошибка возникает на строчке:
Код:
r:=IXMLNode(Pointer(checklistbox1.Items.Objects[i]));
В прикрепленном файле исходный файл.
Вложения
Тип файла: zip Unit1.zip (1.3 Кб, 21 просмотров)

Последний раз редактировалось aspire89; 27.03.2011 в 22:23.
aspire89 вне форума Ответить с цитированием
Старый 27.03.2011, 23:17   #6
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,527
По умолчанию

ну если не нравится
r:=IXMLNODE(Pointer(CheckListBox1.I tems.Objects[i]));
давай попробуем чуток по другому.
j:=integer(CheckListBox1.Items.Obje cts[i]);

Во вложении твой модуль переделанный на новый вариант.
мои исправления выделены серией
///////////// ОТ
...........
//////////// ДО

P.S. сначала можешь поробовать заменить нашу проблемную строчку вот так.
убрать Pointer
r:=IXMLNODE(CheckListBox1.Items.Obj ects[i]);
у меня так не компилилось но вдруг у тебя сработает.
Вложения
Тип файла: zip Unit1.zip (1.4 Кб, 37 просмотров)
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 27.03.2011 в 23:24.
evg_m вне форума Ответить с цитированием
Старый 28.03.2011, 00:33   #7
aspire89
 
Регистрация: 27.03.2011
Сообщений: 4
Хорошо

Без Pointer тоже не компилировалось. Но то, что вы исправили в исходнике работает. Спасибо огромное.
aspire89 вне форума Ответить с цитированием
Старый 27.09.2013, 00:07   #8
vasyaman
Новичок
Джуниор
 
Регистрация: 26.09.2013
Сообщений: 1
По умолчанию

Хотя теме и больше двух лет, но она нашлась в яндексе и хочется сказать большое спасибо evg_m за рабочий код
vasyaman вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
сформировать xml-файл на основе другого xml-файла NieL Общие вопросы Delphi 2 21.12.2010 15:49
Разбор текстового файла в PGN формате Magnum2 Общие вопросы Delphi 0 03.10.2010 00:17
Разбор файла OBJ_TEST russian-stalker Общие вопросы Delphi 11 25.08.2008 11:37
Разбор XML-документов Aiorosu БД в Delphi 0 19.07.2008 20:25
Задание на анализ и разбор xml файла JazonDinAlt Помощь студентам 3 04.05.2008 16:08