lazers pewpewpew
lazers pewpewpew

Reputation:

trouble programming with xml files in delphi

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

Answers (4)

KevinRF
KevinRF

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

Ken White
Ken White

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

Toon Krijthe
Toon Krijthe

Reputation: 53476

Just a few remarks on the code:

  • please don't use uppercase for reserved words.
  • use try finally for created objects
  • use extra begin/end blocks for nested complex statements
  • you forgot an end ;-)
  • use functions
  • try to use an else clause in a case statement

/

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

schnaader
schnaader

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

Related Questions