Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.02.20;
Скачать: CL | DM;

Вниз

Обработка 3000 xml файлов   Найти похожие ветки 

 
s_ilnar ©   (2005-01-18 21:13) [0]

Имеются более 3000 фалов приблизительно такого содержания (и кол-во увеличивается 500 шт в месяц).
Необходимо Выдергивать некоторые данные

Я пока вижу 2 варианта
1. Подключаться к файлу как к базе данных
2. Открывать файл и получать данные следующим способом
-------------------------------------------------------------------------------------------------------------------
function Xml(FileName:string;Key:string):string;
var
F:File;
Str:array [1..3000] of char;
ss:string;
begin
 AssignFile(F,FileName);
 Reset(F);
 BlockRead(F,Str,FileSize(F));
 CloseFile(F);
 ss:=str;
 if pos("<"+key+">",ss)=0 then begin xml:="###Error###"; exit; end;
 Delete(ss,1,pos("<"+key+">",ss)+length(key)+1);
 Delete(ss,pos("<",ss),length(ss));
 Xml:=ss;
end;
--------------------------------------------------------------------------------------------------------------------

МАСТЕРА пожалуйста помогите что делать т.к. файлов более 3000 и обрабатывать эту кучу долговато

Что рекомендуете

-----------------------------------
XML File
-------------------------------
<?xml version="1.0" encoding="windows-1251"?>
<CONTRACT>
<Status>0</Status>
<DealerCode>E000</DealerCode>
<DealerPointCode>E000001</DealerPointCode>
<DealerContractCode>4</DealerContractCode>
<DealerContractDate>2003-12-16</DealerContractDate>
<ABSContractCode></ABSContractCode>
<CUSTOMER>
<CUSTOMERTYPESId>0</CUSTOMERTYPESId>
<SPHERESId>-1</SPHERESId>
<Resident>1</Resident>
<Ratepayer>1</Ratepayer>
<PERSON>
<PERSONTYPESId>0</PERSONTYPESId>
<PERSONNAME>
<SEXTYPESId>0</SEXTYPESId>
<LastName>Иванов</LastName>
<FirstName>Иван</FirstName>
<SecondName>Иванович</SecondName>
</PERSONNAME>
<DOCUMENT>
<DOCTYPESId>1</DOCTYPESId>
<Seria>1010</Seria>
<Number>101010</Number>
<GivenBy>Ивановским РОВД</GivenBy>
<Date>2000-00-00</Date>
<Birthday>2000-00-00</Birthday>
</DOCUMENT>
<INN></INN>
</PERSON><ADDRESS>
<ZIP>400000</ZIP
><Country>Российская Федерация</Country>
<Area></Area>
<Region></Region>
<PLACETYPESId>2</PLACETYPESId>
<PlaceName>Иванов</PlaceName>
<STREETTYPESId>1</STREETTYPESId>
<StreetName>Ивановская</StreetName>
<House>48</House>
<BUILDINGTYPESId>-1</BUILDINGTYPESId>
<Building></Building>
<ROOMTYPESId>-1</ROOMTYPESId>
<Room></Room>
</ADDRESS>
</CUSTOMER>
<BANKPROPLIST/>
<DELIVERY>
<DELIVERYTYPESId>1</DELIVERYTYPESId>
<ADDRESS>
<ZIP>422110</ZIP>
<Country>Российская Федерация</Country>
<Area></Area>
<Region></Region>
<PLACETYPESId>2</PLACETYPESId>
<PlaceName>Иванов</PlaceName>
<STREETTYPESId>1</STREETTYPESId>
<StreetName>Ивановская</StreetName>
<House>48</House>
<BUILDINGTYPESId>-1</BUILDINGTYPESId>
<Building></Building>
<ROOMTYPESId>-1</ROOMTYPESId>
<Room></Room>
</ADDRESS>
<Notes></Notes>
</DELIVERY>
<CONTACT>
<PERSONNAME>
<SEXTYPESId>0</SEXTYPESId>
<LastName>Иванов И.И.</LastName>
<FirstName></FirstName>
<SecondName></SecondName>
</PERSONNAME>
<PhonePrefix>900</PhonePrefix>
<Phone>000000</Phone>
<FaxPrefix></FaxPrefix>
<Fax></Fax>
<EMail></EMail>
<PagerOperatorPrefix></PagerOperatorPrefix>
<PagerOperator></PagerOperator>
<PagerAbonent></PagerAbonent>
<Notes></Notes>
</CONTACT>
<CONNECTIONS>
<CONNECTION>
<PAYSYSTEMSId>3</PAYSYSTEMSId>
<BILLCYCLESId>-1</BILLCYCLESId>
<CELLNETSId>2</CELLNETSId>
<PRODUCTSId>1000</PRODUCTSId>
<PhoneOwner>1</PhoneOwner>
<SerNumber>520000000000000</SerNumber>
<SimLock>0</SimLock>
<IMSI>897000000000000000</IMSI>
<MOBILES>
<MOBILE>
<CHANNELTYPESId>1</CHANNELTYPESId>
<CHANNELLENSId>0</CHANNELLENSId>
<SNB>9000000000</SNB>
<BILLPLANSId>392</BILLPLANSId>
<SERVICES>
<SERVICESId>1</SERVICESId>
<SERVICESId>3</SERVICESId>
<SERVICESId>16</SERVICESId>
<SERVICESId>17</SERVICESId>
<SERVICESId>8</SERVICESId>
</SERVICES>
</MOBILE>
</MOBILES>
</CONNECTION>
</CONNECTIONS>
<Comments></Comments>
<CLIENTVER>1.0.0.275</CLIENTVER>
</CONTRACT>

-------------------------------------


 
Alex_Bredin ©   (2005-01-18 21:24) [1]

в D7 есть библиотеки MSXML, MSXMLDOM, c их помощью можно парсить ХМЛ примерно так(кода кусок):


var
 xml: IXMLDOMDocument;
 n, nn, nnn, nnnn: IXMLDOMNode;
 Query: TTransactionQuery;
 TransactionType: TTransactionType;

begin
 if not fileexists(XMLFileName) then
   raise Exception.Create(Format(RsFileNotFound,[XMLFileName]));
  Result:= TStringList.Create;
  xml := CreateDOMDocument;
  xml.load(XMLFileName);
  n := xml.firstChild;
  while Assigned(n) do
  begin
    if n.nodeName ="нужная нода" then
     begin
      nn:=n.firstChild;
      while assigned(nn) do
        begin
            if nn.nodeName = "еще нужная дочерняя нода" then
              begin
 


итд итп

плохо что все это недокументировано, но есть MSDN, да и Code completion помогает


 
Anatoly Podgoretsky ©   (2005-01-18 21:36) [2]

А вот что ты будешь делать, когда  размер файоа окажется больше 3000 байт
BlockRead(F,Str,FileSize(F));
Тем более, что Str по сути не используется.


 
s_ilnar ©   (2005-01-18 21:50) [3]

Alex_Bredin скорее всего мой способ работает быстрее

и на счет str и ss переменных
(ss:string; str:array[1..3000] of char;)
по идее string=255 символов, но когда я ss:=str то ы в ss лежало более 2500 символов. Как это можете обьяснить
И еще файлы на данный момент не превышают 3000 байт


 
Anatoly Podgoretsky ©   (2005-01-18 22:02) [4]

По идее string это до 2 миллиардов символов.
И по второй идее, это на данный момент.


 
Fay ©   (2005-01-18 23:02) [5]

Блин! Чё за уродскай формат?! Кто придумал вытаскивать атрибуты в элементы?!

По вопросу. Какого размера будут файлы?


 
Anatoly Podgoretsky ©   (2005-01-18 23:18) [6]

Fay ©   (18.01.05 23:02) [5]
Это не важно если не использовать Hard Coded массивов и при это не проверять файл на допустимость.


 
Fay ©   (2005-01-19 00:36) [7]

Anatoly Podgoretsky ©   (18.01.05 23:18) [6]
Если это о размере, то попробуйте открыть в IE такой XML размером ~ 10Мб.


 
Ditrix ©   (2005-01-19 10:23) [8]

может выход такой?
использовать XML только как формат импорта-експорта данных
а для хранения использовать RDBM


 
s_ilnar ©   (2005-01-19 10:59) [9]

Мастера мне необходимо чтоб считывание файлов проходило быстро!!!
Предложите пжлста способ как это реализовать

СПАСИБО


 
Соловьев ©   (2005-01-19 11:09) [10]

Ужас. вот что значит использовать формат не по назначению.
Когда-то писал парсер xml на С - работает шустро, напиши длл на Visual C++ и  дергай ее, пусть тебе она возращает строку или нужный отпарсеный результат.


 
Erik1 ©   (2005-01-19 11:09) [11]

Только кешировать это дело, или изменить постановку задачи. Приведи полностью проблему.


 
s_ilnar ©   (2005-01-19 11:22) [12]

Проблема в следующем
Имеется боолее 3000 файлов (для каждого клиента заводиться отдельный файл, эти файлы создаются не моей программой а обробатывать их надо моей программой
че предложите, когда обробатывается  300 файлов терпеть еще можно
но когда все 3000 файлов это занимает определенное время (~3 мин)

И самая большая проблема надо их еще сортировать по дате,
а дата как вы понимаете записан в файле и считывать как я понимаю придется вся базу (все 3000 файлов)

Ладно у меня их 3000,а у други более 50000

ПОМОГИТЕ


 
Alex_Bredin ©   (2005-01-19 11:25) [13]

разбери файлы один раз, загони данные в БД и работай с ней


 
s_ilnar ©   (2005-01-19 11:32) [14]

Alex_Bredin

Я тоже так думал но есть небольшая заминка иногда эти файлы могут редактироваться


 
Соловьев ©   (2005-01-19 12:07) [15]

А что если загнать файлі в блоб поля и на сервере их парсить?
Кажись в MS SQL есть такая фича... Или FireBird - UDF


 
DSKalugin ©   (2005-01-19 13:09) [16]

у меня тоже стоит подобная задача.
Я собираюсь загнать это все в строку AnsiString и вырезать информацию между нужными тегами, двигаясь вдоль строки.
Но работаю как  с обычным текстовым файлом

var RenaultF:TextFile;
   strKAFile:AnsiString;
begin
 if not OpenDialog.Execute then exit;
 AssignFile(RenaultF,OpenDialog.FileName);
 try
   Reset(RenaultF);
   Read(RenaultF,strKAFile);
 finally
   CloseFile(RenaultF);
 end;
....


 
Arm79 ©   (2005-01-20 14:24) [17]

А если вместо DOM использовать SAX с одновременным внесением данных в БД?


 
vizcoldy   (2005-01-20 16:29) [18]

Если не секрет, чем программа занимется - это ведь файлы Dol, я тут недавно писала кое-что, связанное сней и с этими файлами?


 
s_ilnar ©   (2005-01-23 10:40) [19]

vizcoldy
ТЫ ПРАВ
Че ты под нее писал

Я пишу отчет месячный и ежедневный для отправки в представитьства beeline


 
Ломброзо ©   (2005-01-23 15:49) [20]

ИМХО тут решать все проблемы "в лоб" глупо и вообще пустая трата времени. Совет такой: сесть за изучение .NET, XML, XML Schemas. Что-то мне подсказывает, что раз Beeline требует файлы именно такого формата, то их софтина, занимающаяся разбором, использует какую-то XSD-схему или для десериализации этого XML в какие-то объекты, или для десериализации его в дотнетовский "оторванный" DataSet, который в свою очередь сливает данные в реляционную базу данных. Так что имеет смысл связаться с представительством, поинтересоваться у них механизмом обработки отчётов, попросить схему, помучать .NET  и пр.


 
Ломброзо ©   (2005-01-23 15:51) [21]

Другой вариант - помучать XSLT для трансформации древовидных данных в плоский табличный вид.


 
s_ilnar ©   (2005-01-24 08:47) [22]

Вы мне скажите если работать с файлами как с базой данных это будет быстрее чем как с файлами.

Я думаю что результат будет один и тот же т.к. подключить файл как базу данных и пока какой нибудь dataset считает его мои код за тоже время сумеет его обработать (код на самом верху)


 
Erik1 ©   (2005-01-24 11:16) [23]

Вобщето есть простое решение, странно что некто непредложил. Делаем так сначала импортируем все данные в базу данных, можно многопоточным образом. В базе создаем заголовочную таблицу где записываем имя файла, его дату создания и ID. При следущем старте поверяем какие файлы изменились. Если фаил изменился по парсим его и синхронизуем данные в базе. Опятьтаки все можно делать в потоках, да и изменяться наверное не все файлы. :) Вобще выйгрыш может достигать до 10 раз 10000%!


 
DSKalugin ©   (2005-01-24 11:42) [24]

Даю мой пример. Сделай по образу и подобию.

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
 <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
   <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:Locale="ru-RU">
     <xs:complexType>
       <xs:choice maxOccurs="unbounded">
         <xs:element name="tovar">
           <xs:complexType>
             <xs:sequence>
               <xs:element name="id" type="xs:int" minOccurs="0" />
               <xs:element name="Name" type="xs:string" minOccurs="0" />
               <xs:element name="Car" type="xs:string" minOccurs="0" />
               <xs:element name="Price" type="xs:double" minOccurs="0" />
               <xs:element name="Big_grup" type="xs:int" minOccurs="0" />
               <xs:element name="Sub_grup" type="xs:int" minOccurs="0" />
               <xs:element name="Sklad" type="xs:double" minOccurs="0" />
               <xs:element name="Sklad2" type="xs:int" minOccurs="0" />
               <xs:element name="Sklad3" type="xs:int" minOccurs="0" />
               <xs:element name="ID_ZAMENI" type="xs:int" minOccurs="0" />
             </xs:sequence>
           </xs:complexType>
         </xs:element>
         <xs:element name="news">
           <xs:complexType>
             <xs:sequence>
               <xs:element name="Id" type="xs:int" minOccurs="0" />
               <xs:element name="NEWS" type="xs:string" minOccurs="0" />
               <xs:element name="Date" type="xs:dateTime" minOccurs="0" />
             </xs:sequence>
           </xs:complexType>
         </xs:element>
         <xs:element name="BigGrup">
           <xs:complexType>
             <xs:sequence>
               <xs:element name="ID" type="xs:int" minOccurs="0" />
               <xs:element name="Name" type="xs:string" minOccurs="0" />
             </xs:sequence>
           </xs:complexType>
         </xs:element>
         <xs:element name="SubGrup">
           <xs:complexType>
             <xs:sequence>
               <xs:element name="BIG_ID" type="xs:int" minOccurs="0" />
               <xs:element name="ID" type="xs:int" minOccurs="0" />
               <xs:element name="Name" type="xs:string" minOccurs="0" />
               <xs:element name="Percent" type="xs:int" minOccurs="0" />
             </xs:sequence>
           </xs:complexType>
         </xs:element>
       </xs:choice>
     </xs:complexType>
   </xs:element>
 </xs:schema>
 <tovar>
   <id>1</id>
   <Name>000056</Name>
   <Car>VALEO Комплект сцепления 56</Car>
   <Price>108.75</Price>
   <Big_grup>14</Big_grup>
   <Sub_grup>49</Sub_grup>
   <Sklad>0</Sklad>
   <Sklad2>0</Sklad2>
   <Sklad3>0</Sklad3>
 </tovar>
 <tovar>
   <id>2</id>
   <Name>000057</Name>
   <Car>VALEO Комплект сцепления 57</Car>
   <Price>135.94</Price>
   <Big_grup>14</Big_grup>
   <Sub_grup>49</Sub_grup>
   <Sklad>0</Sklad>
   <Sklad2>0</Sklad2>
   <Sklad3>0</Sklad3>
 </tovar>
..............


 
DSKalugin ©   (2005-01-24 11:42) [25]

а вот сам код чтения XML и экспорт его в Парадокс-таблицу
Писано на скору руку. Вылизывать код потом буду. так что сильно к меткам не придерайтесь.

implementation {$R *.dfm}  uses strutils;
const defdir="u:\Almar";
var strXMLFile,UTF8FileName, ANSIFileName:AnsiString;
   rcnt:LongInt;

procedure TForm1.Button1Click(Sender: TObject);

label r,Start;

const FieldCount=10;
     oTovarTag="<tovar>";
     cTovarTag="</tovar>";

type TXMLStruct=array [1..FieldCount] of ShortString;

var AlmarF:TextFile;
   i,ol,fl:LongInt;
   val:AnsiString;
   oTovarStruct, TovarStruct:TXMLStruct;

begin
 OpenDialog.InitialDir:=defdir;
 OpenDialog.Filter:="obnovlenie.xml|obnovleni*.xml";
 if not OpenDialog.Execute then exit;
 UTF8FileName:=OpenDialog.FileName;
 XMLUtf8ToAnsi(UTF8FileName,ANSIFileName);
 TovarStruct[1]:="id";
 TovarStruct[2]:="Name";
 TovarStruct[3]:="Car";
 TovarStruct[4]:="Price";
 TovarStruct[5]:="Big_grup";
 TovarStruct[6]:="Sub_grup";
 TovarStruct[7]:="Sklad";
 TovarStruct[8]:="Sklad2";
 TovarStruct[9]:="Sklad3";
 TovarStruct[10]:="ID_ZAMENI";
 for i:=1 to FieldCount do begin
   oTovarStruct[i]:="<"+TovarStruct[i]+">";
   StringGrid1.Cells[i-1,0]:=TovarStruct[i];
 end;
 AssignFile(AlmarF,ANSIFileName);
 FileMode := 0;
 StatusBar.Panels[3].Text:=ANSIFileName;
 rcnt:=0;
 try
   Reset(AlmarF);
   StringGrid1.Hide;
   while not Eof(AlmarF) do begin
     ReadLn(AlmarF,strXMLFile);
     strXMLFile:=Trim(strXMLFile);
     if strXMLFile=oTovarTag then begin
       inc(rcnt); i:=1;
       StringGrid1.RowCount:=rcnt+1;
       repeat
         strXMLFile:="";
r:
         ReadLn(AlmarF,val);
         val:=Trim(val);
         if (val[Length(val)]<>">") then begin
           strXMLFile:=strXMLFile+val+" ";
           goto r;
         end
         else strXMLFile:=strXMLFile+val;
Start:
         if AnsiStartsStr(oTovarStruct[i], strXMLFile)
         then begin
           ol:=Length(oTovarStruct[i]);
           fl:=Length(strXMLFile);
           StringGrid1.Cells[i-1,rcnt]:=Copy(strXMLFile,ol+1,fl-2*ol-1);
         end
         else begin
           StringGrid1.Cells[i-1,rcnt]:="?";
           inc(i);
           if (i<=FieldCount) then goto Start;
         end;
         inc(i);
       until ((strXMLFile=cTovarTag) or (i>FieldCount));
// for testing if rcnt=50 then break;
     end;
     Application.ProcessMessages;
   end;
 finally
   StatusBar.Panels[3].Text:=IntToStr(rcnt);
   StringGrid1.Show;
   CloseFile(AlmarF);
 end;
 ShowMessage("Reading Over")
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
 Close
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 StatusBar.Panels[1].Text:="";
 StatusBar.Panels[3].Text:="";
 StringGrid1.ColWidths[0]:=50;
 StringGrid1.ColWidths[1]:=125;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
 SetLength(strXMLFile,0);
 Session.Close;
end;

procedure TForm1.SpeedButton3Click(Sender: TObject);
var i:LongInt;
begin
 Session.Close;
 tbPrice.EmptyTable;
 tbPrice.Open;
 for i:=1 to rcnt do begin
   tbPrice.Append;
   tbPriceid.AsInteger:=StrToInt(StringGrid1.Cells[0,i]);
   tbPriceName.AsString:=StringGrid1.Cells[1,i];

   if StringGrid1.Cells[2,i]<>"?" then tbPriceCar.AsString:=StringGrid1.Cells[2,i];
   tbPricePrice.asFloat:=StrToFloat(StringGrid1.Cells[3,i]);
   tbPriceBig_grup.AsInteger:=StrToInt(StringGrid1.Cells[4,i]);
   tbPriceSub_Grup.AsInteger:=StrToInt(StringGrid1.Cells[5,i]);
   tbPriceSklad.AsInteger:=StrToInt(StringGrid1.Cells[6,i]);
   tbPriceSklad2.AsInteger:=StrToInt(StringGrid1.Cells[7,i]);
   tbPriceSklad3.AsInteger:=StrToInt(StringGrid1.Cells[8,i]);
   if StringGrid1.Cells[9,i]<>"?" then tbPriceId_zameni.AsInteger:=StrToInt(StringGrid1.Cells[9,i]);
   tbPrice.Post;
   Application.ProcessMessages;
 end;
 tbPrice.Close;
 ShowMessage("ok")
end;

procedure TForm1.SpeedButton2Click(Sender: TObject);
var c,r:LongInt;
begin
  c:=StrToInt(Edit1.Text);
  for r:=1 to rcnt do
      if StringGrid1.Cells[c,r]="?" then begin
         StringGrid1.Col:=c;
         StringGrid1.Row:=r;
         Abort
      end;
end;

procedure TForm1.XMLUtf8ToAnsi(const iFileName: AnsiString; var oFileName: AnsiString);
var UTF_F,ANSI_F:TextFile;
   sBuf: WideString;
   dBuf: AnsiString;
begin
 oFileName:=ExtractFilePath(iFileName)+"obnovlenie.ANSI.xml";
 AssignFile(UTF_F,iFileName);
 AssignFile(ANSI_F,oFileName);
 Reset(UTF_F);
 Rewrite(ANSI_F);
 try
 while not EOF(UTF_F) do begin
   ReadLn(UTF_F,sBuf);
   dBuf:=Utf8ToAnsi(sBuf);
   WriteLn(ANSI_F,dBuf);
 end;
 finally
   CloseFile(UTF_F);
   CloseFile(ANSI_F);
 end;
end;

end.


 
DSKalugin ©   (2005-01-24 11:49) [26]

label r
предназначена для склеивания строк, которые разорваны переносом типа

<Car>VALEO Комплект
сцепления
57</Car>

label Start;
предназначена для пропуска отсутствующих полей. Напимер поля <Car> в записи может не быть


 
Erik1 ©   (2005-01-24 16:19) [27]

to DSKalugin
Ну и причем тут твой пример. У человека 5000 файлов и даже простой цикл поиска по ним занимает огромное количество времени! Чем ему поможет твой пример?
 А вот база поможет, поскольку позволяет создать индексы, а с их использованием поиск ускоряется на порядки.


 
Ломброзо ©   (2005-01-24 21:01) [28]

DSKalugin ©   (24.01.05 11:42) [24]

Гениально. Не перевелись ешё кулибины на Руси. Снимаю шапочку. Признайтесь, Вы носки паяльником никогда не пробовали гладить?



Страницы: 1 вся ветка

Текущий архив: 2005.02.20;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.043 c
1-1107842354
Innuendo
2005-02-08 08:59
2005.02.20
Курсор в TEdit


3-1106549717
Alx2
2005-01-24 09:55
2005.02.20
Сортировка набора, возвращаемого хранимой процедурой


14-1107338274
syte_ser78
2005-02-02 12:57
2005.02.20
блин!


14-1106919660
Околокомпьютерный
2005-01-28 16:41
2005.02.20
Про музычку


1-1107844307
Gost
2005-02-08 09:31
2005.02.20
Как "просканировать" каталог на наличие в нем определ. файлов?