Reputation:
Hi I am a beginner programmer tyring to use TXMLparser with Delphi to just read a small xml file so I can understand how they work.
I have the following structure in xml file 'parser.xml' ;
<rule>
<alert>priority 3</alert>
<desc> </desc>
<action>beep</action>
</rule>
And I have the following code in delphi
VAR
Parser : TXmlParser;
rule, alert: string;
i:integer;
BEGIN
Parser := TXmlParser.Create;
Parser.Normalize := TRUE;
Parser.LoadFromFile ('c:\parser.xml');
Parser.StartScan;
WHILE Parser.Scan DO
CASE Parser.CurPartType OF
ptStartTag,
ptEmptyTag :
For i:=0 TO Parser.CurAttr.Count-1 Do
Begin
rule :=Parser.CurAttr.rule (i);
alert :=Parser.CurAttr.alert (i);
ptContent,
ptCData : // Process Parser.CurContent field here
ptEndTag : // Process End-Tag here (Parser.CurName)
ptPI : // Process PI here
// (Parser.CurName is the target, Parser.CurContent)
END;
Parser.Free;
end.
I dont understand where, and with what syntax (e.g. or 'rule' or rule) I am to enter in the xml tags. I obtained the base of the code from the XML website, but the FOR loop is mine.. Seems to work ok but rule and alert come back as undeclared identifiers, even though they are set in VAR
Any help on where to enter and how to enter the tags and why identifiers arent recognised would be appreciated.
Thanks
Upvotes: 0
Views: 1126
Reputation: 602
Take a look at using Delphi's built in XML Databinding Wizard. It can create strongly typed class wrapper around the XML/schema so working with the XML is as easy as any other object.
ex. rule.Alert := 'Alert'; rule.Description := 'Hello'; rule.Action := 'beep';
Upvotes: 1
Reputation: 125757
I'm not a user of TXMLParser, but a quick trip to the documentation section and FAQs page shows the problem.
The problem with the undeclared identifiers isn't because of the variables you've declared in the vars section; it's in the loop on the right side of the assignment (see lines ending in "// ****" comments:
VAR
Parser : TXmlParser;
rule, alert: string;
i:integer;
BEGIN
Parser := TXmlParser.Create;
Parser.Normalize := TRUE;
Parser.LoadFromFile ('c:\parser.xml');
Parser.StartScan;
WHILE Parser.Scan DO
CASE Parser.CurPartType OF
ptStartTag,
ptEmptyTag :
For i:=0 TO Parser.CurAttr.Count-1 Do
Begin
rule := Parser.CurAttr.rule (i); // **** problem here with .rule
alert :=Parser.CurAttr.alert (i); // **** problem here with .alert
ptContent,
ptCData : // Process Parser.CurContent field here
ptEndTag : // Process End-Tag here (Parser.CurName)
ptPI : // Process PI here
// (Parser.CurName is the target, Parser.CurContent)
END;
Parser.Free;
end;
Nothing has established .rule() or .alert as methods of Parser.CurAttr, and you can't treat them as such. Try this instead:
rule := Parser.CurrAttr.Value('rule');
alert := Parser.CurrAttr.Value('alert');
Actually, now that I look more at the XML you posted, you're not dealing with attributes at all, but content instead. Attributes would be along the lines of:
<rule name="My rule" priority="3" alert="Very important">Other stuff</rule>
Still, I'll leave this post just because it explains the syntax error you were having regarding the undeclared identifiers.
Upvotes: 4
Reputation: 53476
Just a few remarks on the code:
/
procedure ProcessXML(const AFileName: string);
var
Parser : TXmlParser;
rule, alert : string;
i : Integer;
begin
Parser := TXmlParser.Create;
try
Parser.Normalize := TRUE;
Parser.LoadFromFile (AFileName);
Parser.StartScan;
while Parser.Scan do begin
case Parser.CurPartType of
ptStartTag,
ptEmptyTag : begin
for i := 0 to Parser.CurAttr.Count-1 do begin
rule :=Parser.CurAttr.rule (i);
alert :=Parser.CurAttr.alert (i);
end;
end;
ptContent,
ptCData : // Process Parser.CurContent field here
ptEndTag : // Process End-Tag here (Parser.CurName)
ptPI : // Process PI here
// (Parser.CurName is the target, Parser.CurContent)
else
// Do something
end;
//
finally
Parser.Free;
end;
end;
And call the function:
begin
ProcessXML('c:\parser.xml');
end.
Look for information on TXMLParser on their site.
Upvotes: 3
Reputation: 49747
The for loop is your problem (or one of them):
ptEmptyTag :
For i:=0 TO Parser.CurAttr.Count-1 Do
Begin
rule :=Parser.CurAttr.rule (i);
alert :=Parser.CurAttr.alert (i);
end; // <-- Insert end here
ptContent,
ptCData : // Process Parser.CurContent field here
ptEndTag : // Process End-Tag here (Parser.CurName)
ptPI : // Process PI here
// (Parser.CurName is the target, Parser.CurContent)
end; // case
Upvotes: 2