unit DocumentStrategy; interface uses Document, CsvParser, XmlParser, XmlInterpreter, XmlInterpreterVisitors; type TCsvStrategy = class(TDocumentStrategy) private FParser : TCsvParser; protected public constructor Create(ADocument : TDocument); override; destructor Destroy; override; procedure SearchAndReplace(const FindText,ReplaceText : string); override; procedure PrettyPrint; override; end; TXmlStrategy = class(TDocumentStrategy) private FParser : TXmlParser; FInterpreter : TXmlInterpreter; FVisitor : TXmlPrettyPrinter; protected public constructor Create(ADocument : TDocument); override; destructor Destroy; override; procedure SearchAndReplace(const FindText,ReplaceText : string); override; procedure PrettyPrint; override; end; implementation uses Classes, SysUtils; { TCsvStrategy } constructor TCsvStrategy.Create(ADocument : TDocument); begin inherited; FParser := TCsvParser.Create; end; destructor TCsvStrategy.Destroy; begin FParser.Free; inherited; end; procedure TCsvStrategy.SearchAndReplace(const FindText,ReplaceText : string); begin Document.Text := StringReplace(Document.Text,FindText,ReplaceText,[rfReplaceAll,rfIgnoreCase]); end; procedure TCsvStrategy.PrettyPrint; const IndentStr = ' '; var TempList : TStringList; FieldList : TStringList; i,j : Integer; Temp : string; begin // Break the document into lines TempList := TStringList.Create; FieldList := TStringList.Create; // Collect result into temporary string in case there is an error Temp := ''; try TempList.Text := Document.Text; for i := 0 to TempList.Count - 1 do begin FParser.ExtractFields(TempList[i],FieldList); // Use simplistic printing scheme of numbering rows, printing fields // on new rows, indented slightly Temp := Temp + Format('Line %d'#13#10,[i]); for j := 0 to FieldList.Count - 1 do begin Temp := Temp + Format('%sField %d = %s'#13#10,[IndentStr,j,FieldList[j]]); end; Temp := Temp + #13#10; end; Document.Text := Temp; finally FieldList.Free; TempList.Free; end; end; { TXmlStrategy } constructor TXmlStrategy.Create(ADocument : TDocument); begin inherited; FParser := TXmlParser.Create; FInterpreter := TXmlInterpreter.Create; FVisitor := TXmlPrettyPrinter.Create; end; destructor TXmlStrategy.Destroy; begin FParser.Free; FInterpreter.Free; FVisitor.Free; inherited; end; procedure TXmlStrategy.SearchAndReplace(const FindText,ReplaceText : string); begin FParser.Parse(Document.Text,FInterpreter.XmlDoc); FInterpreter.XmlDoc.SearchAndReplace(FindText,ReplaceText,False); // Pretty print as well, just so we can get some output FVisitor.Clear; FInterpreter.XmlDoc.Accept(FVisitor); Document.Text := FVisitor.Text; end; procedure TXmlStrategy.PrettyPrint; begin FParser.Parse(Document.Text,FInterpreter.XmlDoc); FVisitor.Clear; FInterpreter.XmlDoc.Accept(FVisitor); Document.Text := FVisitor.Text; end; end.