Solved

Delphi 6 and XML question

Posted on 2009-05-13
12
639 Views
Last Modified: 2012-05-06
How to read a XML file into DataGrid?
0
Comment
Question by:sepknow
  • 4
  • 4
  • 4
12 Comments
 
LVL 8

Expert Comment

by:BdLm
ID: 24382201
could you use MSXML already ?
0
 
LVL 8

Accepted Solution

by:
BdLm earned 400 total points
ID: 24382219
have a look at http://www.efpage.de/DelphiXML.html , I used that lib in several projects and like it.

If you want to copy the xml to a stringGrid or datagrid,   first look for the keywords and the for the text

unit xmlUtilV2;
{******************************************************************************
 *  -->>  see http://www.efpage.de/DelphiXML.html
 *            http://msdn2.microsoft.com/en-us/library/ms757878.aspx
 *
 *  MSXML kapselt die Typelibary zur "MSXML.DLL",
 *  Internetexplorer ab Version 5.0 verfügbar
 *
 *            make msxml data handling more conveniant
 *            source from the Internet
 *
 *
 *
 ******************************************************************************}
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, OleCtrls, msxml, StdCtrls, ComCtrls;
 
const  CodePage = 'Windows-1252';
 
    function nodetype(const n: IxmlDomNode): cardinal;
    function GetNodeText(const n0: IXMLDomNode;const  tag: string): string;
    function GetNodeInt(const XmlNode: IXmlDomNode;const  tag: string): integer;
    function GetNodeDouble(const XmlNode: IXmlDomNode;const  tag: string): double;
    function GetNodeAttribute(const n0: IXMLDomNode;const  tag: string): string;
    procedure GetNodeTextList(const n0: IXMLDomNode;const  tag: string; const result: TstringList);
    function CreateXmlDoc(const RootNodeName: string = 'ROOT'): IXmlDomDocument;
    procedure ClearNode(const node: IXMLDomNode);
    procedure copyDoc(xml,xml2: IxmlDomDocument);
    Function CreateNode(node: IXMLDomNode; nodeName: string): IXMLDomNode;
    Function CreateSingleNode(const node: IXMLDomNode;const  nodeName: string): IXMLDomNode;
    Function CreateText(const node: IXMLDomNode;const  text: string): IXMLDomNode;
    Function CreateTextNode(const node: IXMLDomNode;const  nodeName, text: string): IXMLDomNode;
    function IsTextNode(const node: IXMLDomNode): boolean;
 
    Function CreateSingleTextNode(const node: IXMLDomNode; const  nodeName, text: string): IXMLDomNode;
    Function CreateNodeAttribute(const node: IXMLDomNode;const  attrib, text: string): IXMLDomNode;
    Function CreateSingleAttribute(const node: IXMLDomNode;const  attrib, text: string): IXMLDomNode;
 
    function SelectOrCreateSubNode(const node: IXMLDomNode;const  subnodeName: string): IXMLDomNode;         overload;
    function SelectOrCreateTextNode(const node: IXMLDomNode;const  TextnodeName, Text: string): IXMLDomNode;     overload;
 
 
type
   EValue = class(Exception);
 
implementation
(*---------------------------------------------------------------------
rval: string in Double wandeln ohne Fehlermeldung
      Bei Fehler Rückgabe 0
---------------------------------------------------------------------*)
function rval(const s: string): Double;
var  E: Integer;
begin
{$R-}
    Val(S, Result, E);
    if E<>0 then result := 0;
{$R+}
end;
(*---------------------------------------------------------------------
ival: string in Integer wandeln;
---------------------------------------------------------------------*)
function ival(const s: string): integer;
begin
   result := round(rval(s));
end;
 
 
(************************************************************************
 
				   XML-Dokument neu erzeugen
 
************************************************************************)
 
{ -------------------------------------------------
  Neues Dokument erzeugen und einen Basisknoten mit Namen RootNodeName anhängen
  Wenn ein leerer Name übergeben wird wird kein Basisknoten erzeugt.
  Wenn kein Parameter angegeben wird, dann wird ein Knoten Root erzeugt.
  -------------------------------------------------}
function CreateXmlDoc(const RootNodeName: string = 'ROOT'): IXmlDomDocument;
var
    root: IXMLDomElement;
    PI: IXMLDomProcessingInstruction;
begin
    result := CoDOMDocument.create;
    result.preserveWhiteSpace := True;
    PI := result.CreateProcessingInstruction('xml',
          Format('version="1.0" encoding="%s"', [codepage]));
    result.AppendChild(PI);
    if RootNodeName<>'' then
    begin
        root := result.CreateElement(RootNodeName);
        result.AppendChild(root);
    end;
end;
 
(************************************************************************
 
				   XML-Nodes erzeugen
 
************************************************************************)
 
{ -------------------------------------------------
  Liefert direkt den Typ eines Knotens
  -------------------------------------------------}
function nodetype(const n: IxmlDomNode): cardinal;
begin
    if n.hasChildNodes then
        result :=   n.firstChild.nodeType
    else
        result :=   Node_Invalid;
end;
 
{ -------------------------------------------------
  Alle Subnodes und Attribute löchen
  -------------------------------------------------}
procedure ClearNode(const node: IXMLDomNode);
var s: string;
    parent,newchild: IXMLDomNode;
begin
    s := node.nodeName;
 
    if node.parentNode=Nil then
        exit;
 
    newchild := node.ownerDocument.createElement(s);
    parent := node.parentNode;
    parent.replaceChild(newchild,node);
    newchild := node;
    newchild := Nil;
end;
 
procedure copyDoc(xml,xml2: IxmlDomDocument);
var  node: IxmlDomNode;
begin
    ClearNode(xml2.documentElement);
    node := xml.documentElement.firstChild;
    while node <> nil do
    begin
        xml2.documentElement.appendChild(node.cloneNode(true));
        node := node.nextSibling
    end;
end;
{ -------------------------------------------------
  Knoten erzeugen
  Klammerausdrücke im Namen erzeugen ein Attribut Nr.
  -------------------------------------------------}
Function CreateNode( node: IXMLDomNode; nodeName: string): IXMLDomNode;
var Id: IXMLDomNode;
    attr: string;
begin
   if Node=Nil then
   begin
       result := Nil;
       exit;
   end;
   Id := node.ownerDocument.createElement(NodeName);
   node := node.appendChild(Id);
   result := Node;
end;
 
 
{ -------------------------------------------------
  Knoten erzeugen, wenn er noch nicht existiert
  -------------------------------------------------}
Function CreateSingleNode(const node: IXMLDomNode;const nodeName: string): IXMLDomNode;
var Id: IXMLDomNode;
begin
   if Node=Nil then
   begin
       result := Nil;
       exit;
   end;
   result := node.SelectSingleNode(NodeName);
   if Result = Nil then
   begin
       Id := node.ownerDocument.createElement(NodeName);
       result := node.appendChild(Id);
   end;
end;
 
{ -------------------------------------------------
  Textinhalt eines Knoten erzeugen
  -------------------------------------------------}
Function CreateText(const node: IXMLDomNode;const  text: string): IXMLDomNode;
begin
   if Node=Nil then
   begin
       result := Nil;
       exit;
   end;
   node.appendChild(node.ownerDocument.createTextNode(text));
   result := Node;
end;
 
{ -------------------------------------------------
  Prüfen, ob es sich um einen reinen Textknoten handelt
  -------------------------------------------------}
function IsTextNode(const node: IXMLDomNode): boolean;
var child: IXMLDomNode;
begin
 
    child := node.selectSingleNode('*');
    result := child = Nil;
end;
 
{ -------------------------------------------------
  Knoten mit Textinhalt erzeugen
  -------------------------------------------------}
Function CreateTextNode(const node: IXMLDomNode; const nodeName, text: string): IXMLDomNode;
begin
    result := CreateNode(node,nodename);
    CreateText(result,text);
end;
 
{ -------------------------------------------------
  Knoten mit Textinhalt nur erzeugen, wenn er noch nicht existiert
  sonst den aktuellen Wert überschreiben
  -------------------------------------------------}
Function CreateSingleTextNode(const node: IXMLDomNode; const nodeName, text: string): IXMLDomNode;
begin
    result := node.selectSingleNode(nodeName);
    if result = Nil then
    begin
        result := CreateNode(node,nodename);
        CreateText(result,text);
    end
    else
        result.text := text;
end;
 
{ -------------------------------------------------
  Knoten mit Textinhalt erzeugen
  -------------------------------------------------}
{Function CreateTextNode(doc: IXMLDomDocument; node: IXMLDomNode; nodeName, text: string): IXMLDomNode;
var Id,tx: IXMLDomNode;
begin
   if Node=Nil then
   begin
       result := Nil;
       exit;
   end;
   Id := doc.createElement(NodeName);
   tx := doc.createTextNode(text);
   node := node.appendChild(Id);
   node.appendChild(tx);
   result := Node;
end;
}
Function CreateNodeAttribute(const node: IXMLDomNode; const attrib, text: string): IXMLDomNode;
var    attr: IXmlDomAttribute;
begin
   attr := node.ownerDocument.createAttribute(attrib);
   node.attributes.setNamedItem(attr);
   attr.value := text;
end;
 
Function CreateSingleAttribute(const node: IXMLDomNode; const attrib, text: string): IXMLDomNode;
var    attr: IXmlDomNode;
begin
   attr := node.attributes.getNamedItem(attrib);
   if attr <> Nil then
       attr.text := text
   else
       CreateNodeAttribute(node, attrib, text);
       
end;
 
{ -------------------------------------------------
   Text aus node lesen
  -------------------------------------------------}
function GetNodeText(const n0: IXMLDomNode; const tag: string): string;
var n1: IXMLDomnode;
    i: integer;
begin
    if n0=Nil then begin
        result := '';
        exit;
    end;
    n1 := n0.SelectSingleNode(tag);
    if n1=Nil then
        result := ''
    else
    begin
        result := n1.text;
        repeat
        i := pos('?',result);
        if i>0 then
            result[i] := '-';
        until i<=0;
    end;
end;
 
{ -------------------------------------------------
  Werte aus nodes holen
  Bei fehlendem Eintrag oder leerem Node Rückgabe 0
  -------------------------------------------------}
function GetNodeInt(const XmlNode: IXmlDomNode; const tag: string): integer;
begin
    result := round(GetNodeDouble(XmlNode,tag));
end;
 
function GetNodeDouble(const XmlNode: IXmlDomNode; const tag: string): double;
begin
    if XmlNode<>Nil then
        result := rval(GetNodeText(XmlNode,tag))
    else
        result := 0;
end;
{ -------------------------------------------------
   Attribut lesen
  -------------------------------------------------}
function GetNodeAttribute(const n0: IXMLDomNode; const tag: string): string;
var at: IxmlDomNode;
begin
    result := '';
    if n0=Nil then exit;
    if n0.attributes.length=0 then exit;
    at := n0.attributes.getNamedItem(tag);
    if at=Nil then exit;
    result := at.text;
end;
{ -------------------------------------------------
  Liste von Werten aus einem Knoten lesen
  -------------------------------------------------}
procedure GetNodeTextList(const n0: IXMLDomNode; const tag: string; const result: TstringList);
var n1: IXMLDomnodeList;
    i: integer;
begin
    result.Clear;
    if n0=Nil then begin
        exit;
    end;
    n1 := n0.SelectNodes(tag);
    if n1<>Nil then
    begin
        for i := 0 to n1.length-1 do
            result.Add(n1.item[i].nodeTypedValue);
    end;
end;
{ -------------------------------------------------
  Data-Node suchen nach Id oder ggfs erzeugen
  -------------------------------------------------}
function SelectOrCreateSubNode(const node: IXMLDomNode; const subnodeName: string): IXMLDomNode;
var a: string;
begin
    result := node.selectSingleNode(subnodeName);
 
    if result=Nil then
    begin
        result := node.appendChild(node.ownerDocument.createElement(subnodeName));
        if a <> '' then
            CreateNodeAttribute(result,'Nr',a);
    end;
end;
 
{ -------------------------------------------------
  'Text-Node suchen nach Id oder ggfs erzeugen
  -------------------------------------------------}
function SelectOrCreateTextNode(const node: IXMLDomNode; const TextnodeName, Text: string): IXMLDomNode;     overload;
begin
    result := SelectOrCreateSubnode(node,TextNodeName);
    result.text := Text;
end;
 
 
end.
.

Open in new window

0
 
LVL 26

Assisted Solution

by:EddieShipman
EddieShipman earned 100 total points
ID: 24385811
Can you show the XML you need to parse?

BdLm, that does not solve the OP's question.
That is just a wrapper around MSXML and it looks like it's more for CREATING XML documents.
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

Author Comment

by:sepknow
ID: 24392629
Thanks EddieShipman,
I have list a modifed copy here:

<?xml version="1.0" standalone="yes"?>
<DataFile>
  <AppleInfo>
    <TechAppleID>2020.2</TechAppleID>
    <CustomerAppleID>0209</CustomerAppleID>
    <AppleSegment>;;;</AppleSegment>
    <AppleComment1>-</AppleComment1>
    <AppleComment2>-</AppleComment2>
    <AppleComment3>-</AppleComment3>
    <AppleComment4>-</AppleComment4>
    <AppleComment5>MALAYSIA</AppleComment5>
    <AppleComment6>-</AppleComment6>
    <OrganeCode>HD</OrganeCode>
    <WaferAppleID>-</WaferAppleID>
  </AppleInfo>
  <PineInfo>
    <PineFamily>HB0</PineFamily>
    <PineID>HB0KEB</PineID>
    <JAckComment1>-</JAckComment1>
    <JAckComment2>-</JAckComment2>
    <JAckComment3>...For every Apple</JAckComment3>
    <JAckComment4>-</JAckComment4>
  </PineInfo>
  <BookInfo>
    <Book>300</Book>
    <PDF>TPDF1</PDF>
  </BookInfo>
  <KeyInfo>
    <KeyID>J01</KeyID>
    <KeyGroup>J</KeyGroup>
    <CrowID />
  </KeyInfo>
  <JoinInfo>
    <ANo />
    <BNo />
    <CNo />
    <Reason />
  </JoinInfo>
  <CROSSInfo />
  <MiscInfo>
    <ApplesToOranges />
  </MiscInfo>
  <UserInfo>
    <EmployeeID>ADMIN</EmployeeID>
    <EmployeeName>ADMIN</EmployeeName>
    <TimeStamp>07/04/2009 17:59:26</TimeStamp>
  </UserInfo>
  <AppleInfoService>
    <Quantity />
    <JAckID />
    <Location />
    <SourceAppleID />
    <AppleParameters>
      <AAppleID />
      <GQ-LCOMMENT1 />
      <GQ-LCOMMENT2 />
      <GQ-LCOMMENT3 />
      <GQ-LCOMMENT4 />
      <GQ-LCOMMENT5 />
      <GQ-LCOMMENT6 />
    </AppleParameters>
    <GHParameters>
      <GH-PCOMMENT1 />
      <GH-PCOMMENT2 />
      <GH-PCOMMENT3 />
      <GH-PCOMMENT4 />
    </GHParameters>
    <Categories>
      <C01 />
    </Categories>
  </AppleInfoService>
</DataFile>
0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 24395241
What data do you want in the grid?
Show me some column headers you'd like.
0
 

Author Comment

by:sepknow
ID: 24395383
I would prefer to have two columns only, similar to the ini file format, one for the name and one for the value.
I was also looking into TXMLDocument and was wondering if it is sufficient for my use...
0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 24397705
Yes, to a point but I'd like to see what you want from the data you posted.
0
 
LVL 8

Expert Comment

by:BdLm
ID: 24398746
are the keyword fixed ?

should the grid by like:


xml-keyword      xml-text
...
...
....
....

0
 
LVL 26

Expert Comment

by:EddieShipman
ID: 24398869
There is no way to display that information in a normal grid. This is hierarchical information and thus needs to be displayed in a treeview. Is that acceptable?
0
 
LVL 8

Expert Comment

by:BdLm
ID: 24399687
@eddie: yes,  hierarchical information is then lost  but I think that has been the request,
0
 

Author Comment

by:sepknow
ID: 24400287
Yes, the keywords are fixed, and the grid is exactly wanted.
0
 

Author Closing Comment

by:sepknow
ID: 31581305
I decided to use TXMLDocument instead.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

860 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question