Autor Téma: ListView - Add by Column Name?  (Přečteno 326 krát)

Offline František

  • Hrdina
  • ****
  • Příspěvků: 295
  • Karma: 3
    • Verze Delphi: primárne v XE5, občaas 10.1 starter, XE, BDS2006
ListView - Add by Column Name?
« kdy: 24-11-2017, 12:06:12 »
mam takéto XML
Kód: Delphi [Vybrat]
  1. <zar>
  2.       <kod>AG</kod>
  3.       <pc>0</pc>
  4.       <nazov>Check</nazov>
  5.       <adr>TY</adr>
  6.       <druh>F</druh>
  7. </zar>
  8. <zar>
  9.       <kod>BEZ</kod>
  10.       <pc>1</pc>
  11.       <nazov>Bez</nazov>
  12.       <druh>N</druh>
  13. </zar>

keď sa to snažím naparsovat do ListView
Kód: Delphi [Vybrat]
  1. li := listview1.Items.Add;
  2. li.Caption := KNode.ChildNodes.Nodes[0].text;
  3. for k  := 1 to KNode.ChildNodes.Count -1 do
  4. begin
  5.    li.SubItems.Add(KNode.ChildNodes.Nodes[k].text);
  6. end;

zamozrejme že to priradí podľa poradia a keďže sú tam vynechané prázdne elementy, zaradí to do nesprávneho stĺpčeka

existuje niečo ako databázové filed by name? čo by som porovnal s Caption stĺpčeka?
« Poslední změna: 24-11-2017, 12:09:01 od František »

Offline František

  • Hrdina
  • ****
  • Příspěvků: 295
  • Karma: 3
    • Verze Delphi: primárne v XE5, občaas 10.1 starter, XE, BDS2006
Re:ListView - Add by Column Name?
« Odpověď #1 kdy: 24-11-2017, 12:49:43 »
sfunkčnil som to takto:
Kód: Delphi [Vybrat]
  1.                 x := 1;
  2.                          for k  := 1 to ListView1.Columns.Count -1 do
  3.                          begin
  4.                            if ListView1.Columns.Items[k].Caption = KNode.ChildNodes.Nodes[x].NodeName then
  5.                             begin
  6.                                li.SubItems.Add(KNode.ChildNodes.Nodes[x].text);
  7.                                inc(x);
  8.                             end
  9.                             else li.SubItems.Add('');
  10.                          end;

ale field by column by bolo krajsie :)
« Poslední změna: 24-11-2017, 12:55:16 od František »

Online Delfin

  • Hrdina
  • ****
  • Příspěvků: 439
  • Karma: 23
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:ListView - Add by Column Name?
« Odpověď #2 kdy: 24-11-2017, 14:07:02 »
Na tohle je super SAX parser, staci s kazdou udalosti zpracovani XML node pridat vetev do stromu relativne k posledne pridane.
A co chudinky ovce? Koupíš jim snad plovací vesty? Nebo jim nasadíš chůdy? Ještě lepší, kdybys je zkřížil s delfíny na ovce hopkavé!

Offline František

  • Hrdina
  • ****
  • Příspěvků: 295
  • Karma: 3
    • Verze Delphi: primárne v XE5, občaas 10.1 starter, XE, BDS2006
Re:ListView - Add by Column Name?
« Odpověď #3 kdy: 24-11-2017, 19:57:21 »
no to je ale problém že to dáva za sebou keď je tam nejaký element  vynechaný a tak to priradí zle

Online Delfin

  • Hrdina
  • ****
  • Příspěvků: 439
  • Karma: 23
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:ListView - Add by Column Name?
« Odpověď #4 kdy: 24-11-2017, 20:53:23 »
no to je ale problém že to dáva za sebou keď je tam nejaký element  vynechaný a tak to priradí zle

A jo, to je o list view, ne tree view. Omlouvam se. Nicmene ani tohle neni neresitelne. Zacal bych vsak varovanim abys nepouzival UI komponenty jako storage dat. Data maji byt oddelena od zobrazovace. Vytvoris si kolekci objektu kterou naplnis pri parsovani XML a ty objekty pak zobrazujes v list view ve virtualnim modu (OwnerData). To je postup ktery bych osobne pouzil.

Ad "field by column", nemyslis spis "XML node by list view column caption"? Jen pripomenu, ze se da property IXMLNodeList.Nodes indexovat i za pomoci nazvu node, napr.:

Kód: Delphi [Vybrat]
  1. KNode.ChildNodes.Nodes['NodeName'].NodeValue;
  2. // pripadne zkracene (protoze property Nodes je definovana jako "default")
  3. KNode.ChildNodes['NodeName'].NodeValue;

Btw. co pouzivas za parser; mas i SAX? Vim ze jsi drive psal o mnohamegovem XML, SAX by Ti vykonostne pomohl. Mohl bych napsat konkretni ukazku, jen potrebuju vedet o jaky jde (Ondruv OXml je super, jen skoda ze se nestal FOSS).
« Poslední změna: 24-11-2017, 21:11:11 od Delfin »
A co chudinky ovce? Koupíš jim snad plovací vesty? Nebo jim nasadíš chůdy? Ještě lepší, kdybys je zkřížil s delfíny na ovce hopkavé!

Offline Ondřej Pokorný

  • Guru
  • *****
  • Příspěvků: 710
  • Karma: 43
    • Verze Delphi: Primárně Lazarus, jinak D7 až aktuální
    • Kluug.net
Re:ListView - Add by Column Name?
« Odpověď #5 kdy: 24-11-2017, 23:42:48 »
Nejdřív jsem nechtěl do toho zasahovat, protože stejně už všechno bylo řečeno. Ale přece můj skromný názor: SAX je podle mě na XML nepoužitelná šílenost. To už je lepší použít sekvenční DOM (t.j. XML dokument se čte postupně po elementech a v paměti se drží akorát aktuální element).

Takový malý trénink:

SAX
Kód: Delphi [Vybrat]
  1. program FrSAX;
  2.  
  3. {$APPTYPE CONSOLE}
  4.  
  5. uses
  6.   SysUtils, Generics.Collections,
  7.   OWideSupp, OXmlUtils, OXmlSAX;
  8.  
  9. procedure TestSAX;
  10. var
  11.   xSAX: TSAXParser;
  12.   xRootHandler, xZarHandler: TSAXHandler;
  13.   xProperties: TList<TPair<string,string>>;
  14.   xZarCount: Integer;
  15. begin
  16.   xZarCount := 0;
  17.   xSAX := nil;
  18.   xProperties := nil;
  19.   xRootHandler := nil;
  20.   try
  21.     xSAX := TSAXParser.Create;
  22.     xProperties := TList<TPair<string,string>>.Create;
  23.  
  24.     xRootHandler := TSAXHandler.Create;
  25.     xSAX.ReaderSettings.StrictXML := False;
  26.     xSAX.ReaderSettings.BreakReading := brNone;
  27.     xSAX.Handler := xRootHandler;
  28.     xZarHandler := TSAXHandler.Create;
  29.     xRootHandler.AddChildHandler('zar', xZarHandler);
  30.     xZarHandler.OnStartThisElement :=
  31.       procedure(aSaxParser: TSAXParser;
  32.         const aName: OWideString; const aAttributes: TSAXAttributes)
  33.       begin
  34.         xProperties.Clear;
  35.       end;
  36.     xZarHandler.OnEndThisElement :=
  37.       procedure(aSaxParser: TSAXParser; const aName: OWideString)
  38.       var
  39.         I: Integer;
  40.       begin
  41.         Writeln('zar[', xZarCount, ']');
  42.         for I := 0 to xProperties.Count-1 do
  43.           Writeln(xProperties[I].Key+' = '+xProperties[I].Value);
  44.         Writeln;
  45.         Inc(xZarCount);
  46.       end;
  47.     xZarHandler.OnStartOtherElement :=
  48.       procedure(aSaxParser: TSAXParser; const aName: OWideString; const aAttributes: TSAXAttributes)
  49.       begin
  50.         if aSaxParser.NodePathCount = 2 then
  51.           xProperties.Add(TPair<string,string>.Create(aName, ''));
  52.       end;
  53.     xZarHandler.OnOtherCharacters :=
  54.       procedure(aSaxParser: TSAXParser; const aText: OWideString)
  55.       begin
  56.         if aSaxParser.NodePathCount >= 2 then
  57.           xProperties[xProperties.Count-1] := TPair<string,string>.Create(
  58.             xProperties[xProperties.Count-1].Key, xProperties[xProperties.Count-1].Value+aText);
  59.       end;
  60.  
  61.     xSAX.ParseXML(
  62.       '<zar>'+
  63.         '<kod>AG</kod>'+
  64.         '<pc>0</pc>'+
  65.         '<nazov>Check</nazov>'+
  66.         '<adr>TY</adr>'+
  67.         '<druh>F</druh>'+
  68.       '</zar>'+
  69.       '<zar>'+
  70.         '<kod>BEZ</kod>'+
  71.         '<pc>1</pc>'+
  72.         '<nazov>Bez</nazov>'+
  73.         '<druh>N</druh>'+
  74.       '</zar>');
  75.   finally
  76.     xSAX.Free;
  77.     xProperties.Free;
  78.     xRootHandler.Free;
  79.   end;
  80. end;
  81.  
  82. begin
  83.   TestSAX;
  84.  
  85.   Readln;
  86. end.
  87.  

Sekvenční DOM:
Kód: Delphi [Vybrat]
  1. program FrSeqDOM;
  2.  
  3. {$APPTYPE CONSOLE}
  4.  
  5. uses
  6.   SysUtils, Generics.Collections,
  7.   OWideSupp, OXmlUtils, OXMLPDOM, OXmlPSeq;
  8.  
  9. procedure TestPSeq;
  10. var
  11.   xSeq: TXMLSeqParser;
  12.   xZarCount: Integer;
  13.   xZarNode, xPropertyNode: PXMLNode;
  14.   xOpenElement: Boolean;
  15. begin
  16.   xZarCount := 0;
  17.   xSeq := TXMLSeqParser.Create;
  18.   try
  19.     xSeq.ReaderSettings.StrictXML := False;
  20.     xSeq.ReaderSettings.BreakReading := brNone;
  21.     xSeq.InitXML(
  22.       '<zar>'+
  23.         '<kod>AG</kod>'+
  24.         '<pc>0</pc>'+
  25.         '<nazov>Check</nazov>'+
  26.         '<adr>TY</adr>'+
  27.         '<druh>F</druh>'+
  28.       '</zar>'+
  29.       '<zar>'+
  30.         '<kod>BEZ</kod>'+
  31.         '<pc>1</pc>'+
  32.         '<nazov>Bez</nazov>'+
  33.         '<druh>N</druh>'+
  34.       '</zar>');
  35.  
  36.     while xSeq.ReadNextChildElementHeader(xZarNode, xOpenElement) do
  37.     begin
  38.       if (xZarNode.NodeType = ntElement) and
  39.          (xZarNode.NodeName = 'zar') then
  40.       begin
  41.         Writeln('zar [', xZarCount, ']');
  42.         if xOpenElement then
  43.         begin
  44.           while xSeq.ReadNextChildNode(xPropertyNode) do
  45.             Writeln(xPropertyNode.NodeName, ' = ', xPropertyNode.Text);
  46.           xSeq.GoToPath('../');
  47.         end;
  48.         Writeln;
  49.         Inc(xZarCount);
  50.       end else
  51.       if xOpenElement then
  52.         xSeq.GoToPath('../');
  53.     end;
  54.   finally
  55.     xSeq.Free;
  56.   end;
  57. end;
  58.  
  59. begin
  60.   TestPSeq;
  61.  
  62.   Readln;
  63. end.
Embarcadero Technology Partner, juj. Člen Lazarus týmu, oj.

Online Delfin

  • Hrdina
  • ****
  • Příspěvků: 439
  • Karma: 23
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:ListView - Add by Column Name?
« Odpověď #6 kdy: 24-11-2017, 23:59:00 »
Nejdřív jsem nechtěl do toho zasahovat, protože stejně už všechno bylo řečeno. Ale přece můj skromný názor: SAX je podle mě na XML nepoužitelná šílenost.

Vis urcite vic, ale mas nejaky duvod pro nepouziti SAX pro nacteni (s naslednym zobrazenim treba 100MB XML, coz je samo o sobe, ehm, ...)? Ja tu zminku o 100MB XML objemu (dejte vedet pokud se pletu) zahledl v nekterem z prispevku autora a chapu ze ohromny objem dat nabizeny uzivateli je nesmysl. SAX by ale v tomto pripade pomohl, nebo mas jine vysledky?

Rekneme ze bychom zustali o seskladani kolekce objektu (a vyuziti list view ve virtualnim rezimu). Myslis, nebo vis ze by pro sestaveni konkretni kolekce nodes bylo rychlejsi DOM oproti SAX? Teoreticky by nemelo...
« Poslední změna: 25-11-2017, 00:00:31 od Delfin »
A co chudinky ovce? Koupíš jim snad plovací vesty? Nebo jim nasadíš chůdy? Ještě lepší, kdybys je zkřížil s delfíny na ovce hopkavé!

Offline Ondřej Pokorný

  • Guru
  • *****
  • Příspěvků: 710
  • Karma: 43
    • Verze Delphi: Primárně Lazarus, jinak D7 až aktuální
    • Kluug.net
Re:ListView - Add by Column Name?
« Odpověď #7 kdy: 25-11-2017, 00:10:49 »
Excellent
Rated 1 time
SAX bude vždycky rychlejší než jakýkoliv DOM. Ale strašně blbě a nepřehledně se s tím pracuje. Anonymní metody tomu trochu pomohly, ale i tak člověk slepuje data z všeljakých eventů.
Embarcadero Technology Partner, juj. Člen Lazarus týmu, oj.

Online Delfin

  • Hrdina
  • ****
  • Příspěvků: 439
  • Karma: 23
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:ListView - Add by Column Name?
« Odpověď #8 kdy: 25-11-2017, 00:16:19 »
SAX bude vždycky rychlejší než jakýkoliv DOM. Ale strašně blbě a nepřehledně se s tím pracuje. Anonymní metody tomu trochu pomohly, ale i tak člověk slepuje data z všeljakých eventů.

Ne zas tak "blbe", pokud vis jaky XML node "potrebujes". Jinak, pokud je ucelem aby OP "zobrazil" 100MB XML v list view (ja tech 100MB nekde predtim videl, mozna se pletu; predchozi diskuze byly moc dlouhe), pak bych volil SAX parser ve vlakne a po (nebo pri; v pripade ze bude SAX parser umet moznost zacit parsovat a ukocit parsovani ve vybranem okamziku - elementu XML [s rizikem moznych chyb]) vytvoreni kolekce konktretnich objektu bych zobrazoval vysledek ve virtual rezimu list view. Mozna mi ale neco uniklo; no radeji se nebudu motat do neceho co jsem dukladne necetl :-[ :)
« Poslední změna: 25-11-2017, 00:32:38 od Delfin »
A co chudinky ovce? Koupíš jim snad plovací vesty? Nebo jim nasadíš chůdy? Ještě lepší, kdybys je zkřížil s delfíny na ovce hopkavé!

Offline František

  • Hrdina
  • ****
  • Příspěvků: 295
  • Karma: 3
    • Verze Delphi: primárne v XE5, občaas 10.1 starter, XE, BDS2006
Re:ListView - Add by Column Name?
« Odpověď #9 kdy: 25-11-2017, 17:40:54 »
nie, tie 100 MB je mimo toto vlákno o ListView, to rvem z XML do DB, ale každá rada dobra ako to urýchliť (pre 10 rokmi som to riešil cez  TXMLTransformprovider, funguje to doteraz)
« Poslední změna: 25-11-2017, 17:47:22 od František »

 

S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

Jméno: E-mail:
Ověření:
Datový typ v Delphi, který má True a False: