Помогите пожалуйста с запсью/чтеньем XML!!!!

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

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

VinSS
новенький
Сообщения: 26
Зарегистрирован: 29.12.2011 04:23:46

Сообщение VinSS »

ReadXMLFile(Doc, '\\server\types\type_1\all_files\file_00529759\file529759.xml');
PassNode := Doc.DocumentElement.FindNode(WideString('number'));
if not (PassNode=nil) then
begin
s := PassNode.FirstChild.NodeValue;
ShowMessage(s);
end;
Doc.Free;

Код в данный момент такой. PassNode=nil всегда, какой бы Нод я не запрашивал, он даже внутрь не заходит, не пытается что-то вывести, а если условие убрать, то SIGSEVG. Поэтому к сожалению проблема не в методе чтения текста ноды :(

leo_bsv писал(а):атрибут encoding="unicode" не обязателен.

К системе, которая выгружает эти хмлки доступа нет, только к ним.
Аватара пользователя
leo_bsv
постоялец
Сообщения: 276
Зарегистрирован: 04.08.2010 16:26:10
Откуда: Йошкар-Ола
Контактная информация:

Сообщение leo_bsv »

VinSS писал(а):К системе, которая выгружает эти хмлки доступа нет, только к ним.

попробуй вручную снести атрибут encoding="unicode", у меня с ним твой файл вообще не читает прога...
VinSS
новенький
Сообщения: 26
Зарегистрирован: 29.12.2011 04:23:46

Сообщение VinSS »

Все по прежнему :(
Может быть действительно нет рекурсии. Ведь в хмлке в пакете "batch" вложены страницы "page" и только потом блоки с данными "block".
Если подойти к проблеме с другой стороны, то если бы я смог перебрать все имена блоков, то понял бы почему нужный мне не находится. Но тут я снова надеюсь на вас :)

Добавлено спустя 26 минут 9 секунд:
Вот нашел такой вариант:
CurrentNode: IXMLNode;
Batch: TXMLDocument;

Batch.FileName:='file529759.xml';
Batch.Active:=True;

s:=ReadNodeByAttribute('number');
ShowMessage(s);

function TForm1.ReadNodeByAttribute(Attribute: string): string;
begin
CurrentNode:=FindNodeByAttribute(Attribute, 0);
Result:=CurrentNode.NodeValue;
end;

function TForm1.FindNodeByAttribute(Attribute: string; StartNode: integer): IXMLNode;
begin
try
begin
CurrentNode:=Batch.DocumentElement.ChildNodes[StartNode].ChildNodes[0];
while CurrentNode.Attributes['blockName']<>Attribute do
begin
CurrentNode:=CurrentNode.NextSibling;
end;
end;
except
begin
StartNode:=StartNode+1;
CurrentNode:=FindNodeByAttribute(Attribute, StartNode);
end;
end;

Result:=CurrentNode;
end;

Ругается на IXMLNode :( не знаю какой модуль подключить :( чувство у меня есть, что один из этих: xmldom, XMLIntf, msxmldom, XMLDoc. Но ни одного в лазарусе нет :(
Последний раз редактировалось VinSS 02.01.2012 04:03:58, всего редактировалось 2 раза.
Аватара пользователя
leo_bsv
постоялец
Сообщения: 276
Зарегистрирован: 04.08.2010 16:26:10
Откуда: Йошкар-Ола
Контактная информация:

Сообщение leo_bsv »

я не пойму что конкретно ты хочешь почитать из файла хмл
VinSS
новенький
Сообщения: 26
Зарегистрирован: 29.12.2011 04:23:46

Сообщение VinSS »

Пытаюсь послать "SURNAME" - получить "ИВАНОВ", если в хмлке есть <block blockName="SURNAME" l="110" t="521" r="1193" b="607">ИВАНОВ</block>

Добавлено спустя 3 минуты 40 секунд:
Извиняюсь за огромный кусок кода, но он должен быть рабочий, вроде как прогой на его основе пользуются, только разработчика не найти и исходники на делфе.

Добавлено спустя 45 минут 43 секунды:
После всех адаптаций под лазаря, осталось:
unit1.pas(797,44) Error: Incompatible type for arg no. 1: Got "Constant String", expected "LongWord"
на CurrentNode.Attributes['blockName']<>Attribute
Аватара пользователя
leo_bsv
постоялец
Сообщения: 276
Зарегистрирован: 04.08.2010 16:26:10
Откуда: Йошкар-Ола
Контактная информация:

Сообщение leo_bsv »

вот рабочий код:

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

var
  Form1: TForm1;
  Doc: TXMLDocument;
  NeededValue:string;


implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FindIt(Node:TDOMNode);
var
  n: integer;
begin
  // если не определена ветвь - выйдем
  if not Assigned(Node) then exit;
  // для каждой дочерней ветви
  for n:=0 to Node.ChildNodes.Count-1 do begin
    // т.к. нас интересует ветвь с атрибутами, то если их нет - проскочим текущую ветвь
    if not Node.ChildNodes[n].HasAttributes then continue;
    // проверим ветвь на соответствие нужным условиям
    if TDOMElement(Node.ChildNodes[n]).hasAttribute('blockName') then
      if (TDOMElement(Node.ChildNodes[n]).AttribStrings['blockName']=NeededValue) then
        ShowMessage(Node.ChildNodes[n].FirstChild.NodeValue);
    // запустим этот же цикл для дочерних ветвей
    FindIt(Node.ChildNodes[n]);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var s:string;
begin
  ReadXMLFile(Doc,'xmldoc');
  NeededValue:='SURNAME';
  FindIt(Doc);
end; 
Последний раз редактировалось leo_bsv 02.01.2012 11:47:25, всего редактировалось 1 раз.
VinSS
новенький
Сообщения: 26
Зарегистрирован: 29.12.2011 04:23:46

Сообщение VinSS »

Дададададада!!! Спасибо, leo_bsv! Работает! :D
Можно еще пару коментов? :oops: а что если блока такого не будет? Если изначально не забили фамилию, то система выгрузит хмлку, без такого блока вообще. Как отследить? И я буду счастлив! :D

Добавлено спустя 25 минут 3 секунды:
Разобрался! Главное, что не падает, если в NeededValue записать несуществующий блок! Просто идеально! :)

Добавлено спустя 2 минуты 43 секунды:
Осталось разобраться с экселем и отправкой через Lotus :)
Аватара пользователя
VirtUX
энтузиаст
Сообщения: 880
Зарегистрирован: 05.02.2008 09:52:19
Откуда: Крым, Алушта

Сообщение VirtUX »

В XML-файле используется

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

<?xml version="1.0" encoding="windows-1251"?>

При попытке открыть файл

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

if OpenDialogXMLFile.Execute then begin
     ReadXMLFile(Doc, OpenDialogXMLFile.FileName);
     ShowXML;
     Doc.Free;
     end;

Выдает ошибку
Encoding 'windows-1251' is not supported

Как заставить понимать? XML-файлы не мной формируются, мне нужно читать то, что дадут. При чем кодировка может быть какой угодно! Есть-ли универсальное решение?
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

VirtUX писал(а):Как заставить понимать? XML-файлы не мной формируются, мне нужно читать то, что дадут. При чем кодировка может быть какой угодно! Есть-ли универсальное решение?


http://wiki.freepascal.org/XML_Decoders/ru
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

VirtUX писал(а):Как заставить понимать?

Ещё, как вариант, раньше я просто вырезал из файла эту строку:

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

encoding="windows-1251"

и всё открывалось, как родное. Конечно, если русского текста там нету. ;)
Аватара пользователя
VirtUX
энтузиаст
Сообщения: 880
Зарегистрирован: 05.02.2008 09:52:19
Откуда: Крым, Алушта

Сообщение VirtUX »

В том-то и дело, что русского текста там много. Ладно. Открывать понятно как (правда решил этим в последнюю очередь заняться).
Пробую создать простой XML-файл. Но как заставить FPC сохранять его в "windows-1251", и соответственно вписывать эту кодировку в шапке (вместо encoding="utf-8", написать encoding="windows-1251"). Прога, в которую нужно экспортировать обработанные данные поддерживает только эту кодировку. Понятно, что можно перекодировать текстовое тело во время присвоения значения узлу, и после сохранения еще раз открыть созданный файл как текстовый и заменить первую строку на нужную, но... Может есть проще способ?

Добавлено спустя 2 минуты 39 секунд:
Может существуют компоненты с поддержкой разных кодировок? А то мало-ли завтра с Маков начнут скидывать данные в маковской кодировке...
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Сохранение не в utf-8 пока что не поддерживается.
Padre_Mortius
энтузиаст
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

Сообщение Padre_Mortius »

VirtUX, в проекте jedi есть компонент по работе с xml.
Аватара пользователя
VirtUX
энтузиаст
Сообщения: 880
Зарегистрирован: 05.02.2008 09:52:19
Откуда: Крым, Алушта

Сообщение VirtUX »

Jedi - это же, вроде бы как, Delphi-кмпоненты...
Padre_Mortius
энтузиаст
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

Сообщение Padre_Mortius »

VirtUX писал(а):Jedi - это же, вроде бы как, Delphi-кмпоненты...

Без проблем переносится этот компонент под лазарус
Ответить