[ mica99 @ 06.02.2014. 18:15 ] @
Pozdrav,
Kako je moguce da se pronalazi odredjeni nod u jednom child nodu koji nedostaje i da se automatski upisuje.

Primer:

<Main>Neki text>
<A>Neki text</>
<B>Neki text</>
</Main>
.
.
<Main>Neki text>
<A>Neki text</>
<B>Neki text</>
</Main>
.
.
<Main>Neki text>
<A>Neki text</>
<B>Neki text</>
</Main>
.
.
.
Pitanje je kako da pronalazim ako u nekom child nodu fali node B i ako fali da ga automatski upisuje naravno bez ikakvog texta.
Da napomenem jer node B nije uvek drugi po redu

Hvala




[ Rapaic Rajko @ 07.02.2014. 21:42 ] @
Da li namerno ili slucajno ovo pitas na Delphi forumu?

Ako namerno, pa postoje klase za rad sa xml-om. Otprilike bi trebalo da pozivom neke metode parent node-a trazis subnode B; ukoliko ga nema, metoda vraca nil. Ako vrati nil, ti onda kreiras i upisujes (opet metodom parent node-a) novi subnode B. Tako nekako bi trebalo da radi... ;)

Pozz
[ ((BugA)) @ 07.02.2014. 22:07 ] @
Evo nesto za pocetak, pa se ti igraj dalje :)

Code:
uses
  ComObj,
  MSXML;

procedure InsertMissingChildNode(
  AParentNode: IXMLDOMNode;
  AChildName : string;
  AChildValue: string;
  AChildLevel: integer = 1);
var
  i: integer;
  bFound: Boolean;
  xmlNode: IXMLDOMNode;
begin
  bFound := False;
  Dec(AChildLevel);
  //
  for i := 0 to AParentNode.childNodes.length-1 do
  begin
    if (AChildLevel > 0) then
      InsertMissingChildNode(
        AParentNode.childNodes[i],
        AChildName,
        AChildValue,
        AChildLevel
      );
    //
    bFound := (bFound OR (AParentNode.childNodes[i].nodeName = AChildName));
  end;
  //
  if ((not bFound)
    and (AParentNode.nodeType = NODE_ELEMENT)
    and (AChildLevel = 0)) then
  begin
    xmlNode := AParentNode.ownerDocument.createElement(AChildName);
    if (AChildValue <> '') then
      xmlNode.text := AChildValue;
    //
    AParentNode.appendChild(xmlNode);
  end;
end;

Upotreba:
Code:
var
  xmlDoc: IXMLDOMDocument;
  xmlText: string;
begin
  xmlText := '<root>'
    + '  <Main>Neki text'
    + '    <A>Neki text</A>'
    + '    <B>Neki text</B>'
    + '  </Main>'
    + '  <Main>Neki text'
    + '    <A>Neki text</A>'
    //     ovde nedostaje <B/>
    + '  </Main>'
    + '</root>';
  //
  xmlDoc := CreateOleObject('Microsoft.XMLDOM') as IXMLDOMDocument;
  xmlDoc.preserveWhiteSpace := True;
  xmlDoc.loadXML(xmlText);
  //
  InsertMissingChildNode(xmlDoc.firstChild, 'B', '', 2);
  ShowMessage(xmlDoc.xml);
end;

Evo i rezultata u zavisnosti od parametra "AChildLevel":
Code:
Pocetni XML:
<root>
  <Main>Neki text
    <A>Neki text</A>
    <B>Neki text</B>
  </Main>
  <Main>Neki text
    <A>Neki text</A>
  </Main>
</root>

Poziv: InsertMissingChildNode(xmlDoc.firstChild, 'B', '', 2);
Rezultat:
<root>
  <Main>Neki text    
    <A>Neki text</A>
    <B>Neki text</B>
  </Main>
  <Main>Neki text    
    <A>Neki text</A>
    <B/> <-- dodati element (child level 2 u odnosu na root)
  </Main>
</root>

Poziv: InsertMissingChildNode(xmlDoc.firstChild, 'B', '');
Rezultat:
<root>
  <Main>Neki text    
    <A>Neki text</A>    
    <B>Neki text</B>  
  </Main>
  <Main>Neki text    
    <A>Neki text</A>  
  </Main>
  <B/> <-- dodati element (child level 1 u odnosu na root)
</root>

Poziv: InsertMissingChildNode(xmlDoc.firstChild, 'B', '', 3);
Rezultat:
<root>
  <Main>Neki text    
    <A>Neki text
      <B/> <-- dodati element (child level 3 u odnosu na root)
    </A>
    <B>Neki text
      <B/> <-- dodati element (child level 3 u odnosu na root)
    </B>
  </Main>
  <Main>Neki text    
    <A>Neki text
      <B/> <-- dodati element (child level 3 u odnosu na root)
    </A>
  </Main>
</root>

Pozdrav, BugA
[ mica99 @ 08.02.2014. 18:59 ] @
Hvala puno za pomoc
[ mica99 @ 12.02.2014. 13:23 ] @
Izvini sto te opet pitam ali kako da te promene uradim u nekom externom xml fajlu.
Zaci da ucita fajl, uradi promene i da ga sacuva

Hvala ti jos jednom
[ captPicard @ 12.02.2014. 14:34 ] @
Code (delphi):
xmlDoc.loadXML(xmlText);


Varijable xmlText je putanja do .xml fajle (ako sam dobro shvatio kod od Bug-a). Najbolje ti je da staviš npr OpenDialog na formu i onda ovako nekako:

Code (delphi):
if OpenDialog1.Execute then
xmlText:= OpenDialog1.FileName;
[ mica99 @ 12.02.2014. 14:49 ] @
Ne moze jer xmlText je string a mislim da se treba napraviti string list
[ ((BugA)) @ 12.02.2014. 22:53 ] @
Uz ono sto smo ti captPicard i ja vec napisali, to bi moglo da izgleda na primer ovako, upotreba:

Code:
var
  xmlDoc: IXMLDOMDocument;
  openDialog: TOpenDialog;
  sFile: string;
begin
  openDialog := TOpenDialog.Create(nil);
  try
    if (openDialog.Execute) then
    begin
      sFile := openDialog.FileName;
      //
      xmlDoc := CreateOleObject('Microsoft.XMLDOM') as IXMLDOMDocument;
      xmlDoc.preserveWhiteSpace := True;
      xmlDoc.load(sFile);
      //
      InsertMissingChildNode(xmlDoc.firstChild, 'B', '', 2);
      xmlDoc.save(sFile);
    end;
  finally
    openDialog.Free();
  end;
end;

Pozdrav, BugA
[ Rapaic Rajko @ 13.02.2014. 10:43 ] @
Citat:
mica99:
Ne moze jer xmlText je string a mislim da se treba napraviti string list


Malo (samo)inventivnosti ne bi bilo na odmet...

Pozz
[ mica99 @ 13.02.2014. 20:10 ] @
Hvala vam puno za pomoc.