I am attempting to parse this XML file in a Delphi 11.3 (VCL app) using IXMLDocument. I am traversing the tree properly, but I'm not able to extract the values from within the jobbean node. Ideally, I'd like to populate some values into a stringgrid, but for now, I'm just adding them to a TMemo object.
Currently, my XMLMemo object is just being populated with the value of 'j' and the string 'item'. I'd like to grab the item name and the associated value. For example, the string "JobID" and its value "1664-b6b2-ac13-876020240304112009", then "JobVersion" and its value "3.6", and so on.
Here's the XML (stored in FileName) I'm working with:
<root>
<joblist>
<jobbean>
<item name="JobID" value="1664-b6b2-ac13-876020240304112009"/>
<item name="JobVersion" value="3.6"/>
<item name="JobName" value="14509-20240304"/>
<item name="JobState" value="3"/>
<item name="JobStatus" value="2"/>
<item name="CreationDate" value="638451660887232507"/>
<item name="ModifyTime" value="638451663423079957"/>
<item name="Priority" value="1"/>
<item name="Operator" value=""/>
</jobbean>
<jobbean>
<item name="JobID" value="1664-b6b2-ac13-876020240304112547"/>
<item name="JobVersion" value="3.6"/>
<item name="JobName" value="14509-20240304"/>
<item name="JobState" value="3"/>
<item name="JobStatus" value="2"/>
<item name="CreationDate" value="638451660887232507"/>
<item name="ModifyTime" value="638451663423079957"/>
<item name="Priority" value="1"/>
<item name="Operator" value=""/>
</jobbean>
<jobbean>
<item name="JobID" value="1664-b6b2-ac13-876020240304173521"/>
<item name="JobVersion" value="3.6"/>
<item name="JobName" value="AC-7BAD0QHO20240304173528"/>
<item name="JobState" value="4"/>
<item name="JobStatus" value="5"/>
<item name="CreationDate" value="638451885369544727"/>
<item name="ModifyTime" value="638451885369560248"/>
<item name="Priority" value="1"/>
<item name="Operator" value=""/>
</jobbean>
</joblist>
</root>
Here is my Delphi code:
procedure Tfrm_Main.btn_XMLClick(Sender: TObject);
begin
ReadXMLFile(FileName);
end;
procedure Tfrm_Main.ReadXMLFile(const FileName: string);
var
XMLDoc: IXMLDocument;
RootNode, JobListNode, JobBeanNode, ChildNode: IXMLNode;
NodeList: IXMLNodeList;
i, j: Integer;
begin
XMLDoc := TXMLDocument.Create(nil);
try
XMLDoc.LoadFromFile(FileName);
XMLDoc.Active := True;
RootNode := XMLDoc.DocumentElement;
if Assigned(RootNode) then
begin
// Access node properties
JobListNode := RootNode.ChildNodes.FindNode('joblist');
if Assigned(JobListNode) then
begin
for i := 0 to JobListNode.ChildNodes.Count - 1 do
begin
JobBeanNode := JobListNode.ChildNodes[i];
if Assigned(JobBeanNode) then
begin
for j := 0 to JobBeanNode.ChildNodes.Count - 1 do
begin
ChildNode := JobBeanNode.ChildNodes[i];
if Assigned(ChildNode) then
begin
XMLMemo.Lines.Add(IntToStr(j) + ' ' + ChildNode.NodeName);
end;
end;
end;
end;
end;
end;
finally
XMLDoc := nil;
end;
end;
Right now the output looks like:
0 item
1 item
2 item
3 item
4 item
5 item
6 item
7 item
8 item
0 item
1 item
...
How do I extract out of this XML file the values that I need?
The values you are looking for are attributes of the <item>
nodes, but you are not accessing any attributes. Use the IXMLNode.AttributeNodes
or IXMLNode.Attributes[]
property to access them, eg:
for j := 0 to JobBeanNode.ChildNodes.Count - 1 do
begin
ChildNode := JobBeanNode.ChildNodes[i];
name := ChildNode.Attributes['name'];
value := ChildNode.Attributes['value'];
//...
// alternatively:
for k := 0 to ChildNode.AttributeNodes.Count - 1 do
begin
AttrNode := ChildNode.AttributeNodes[k];
name := AttrNode.NodeName;
value := AttrNode.NodeValue;
//...
end;
end;
On a side note - you can replace these 3 lines:
XMLDoc := TXMLDocument.Create(nil);
XMLDoc.LoadFromFile(FileName);
XMLDoc.Active := True;
With 1 line by using the LoadXMLDocument()
function:
XMLDoc := LoadXMLDocument(FileName);