views:

262

answers:

2

I have an interface:

type IXMLSerializable = interface
  function SaveToXML : DOMString;
  function SaveToXMLDocument : IXMLDocument;
  procedure LoadFromXML(AXML : DOMString);
end;

It is used to serialize some settings of forms or frames to xml.

Simple implementation:

SaveToXMLDocument:

function TSomething.SaveToXMLDocument: IXMLDocument;
begin
  Result := TXMLDocument.Create(nil);

  with Result do
  begin
    Active := True;
    with AddChild(Self.Name) do
    begin
      AddChild(edSomeTextBox.Name).Attributes['Text'] := edSomeTextBox.Text;
    end;
  end;
end;

LoadFromXML:

procedure TSomething.LoadFromXML(AXML: DOMString);
var
  XMLDoc : IXMLDocument;
  I : Integer;
begin
  XMLDoc := TXMLDocument.Create(nil);

  with XMLDoc do
  begin
    LoadFromXML(AXML);
    Active := True;
    with ChildNodes[0] do
    begin
      for I := 0 to ChildNodes.Count-1 do
      begin
        If ChildNodes[I].NodeName = 'edSomeTextBox' then
          edSomeTextBox.Text := ChildNodes[I].Attributes['Text'];
      end;
    end;
  end;
end;

SaveToXML:

function TSomething.SaveToXML: DOMString;
begin
  SaveToXMLDocument.SaveToXML(Result);
end;

DOMString result of SaveToXML is saved to database to blob field. I had some encoding issues with other implementations and this one works fine (right now). Do you see any dangers in this code? Can I have issues with different settings on various machines and systems?

edSomeTextBox.Text is string. Attributes are OleVariant. SaveToXml return DOMString, which is WideString. Is it possible that I lose some data here?

+1  A: 

Besides using with? :)

The only thing that jumps out at me is that it looks like every component that's going to be reading it's settings from XML is parsing the entire XML document. That's not going to scale very well at all.

I think that having each object get a TXMLNode to persist to and load from would let you centralize the XML processing. It's a pretty major change to your interface though.

Also, the very last line of TSomething.SaveToXMLDocument, why are you reassigning Result? What's XMLDoc?

afrazier
I deleted last line, thanks. It will not scale well, but it doesn't have to, forms and frames will be simple. I want to make sure that this code will work properly, because I had a lot of problems with string encoding. I used `TXMLDocument.XML.ToString` earlier, which converted xml to string and had issues when loading back.
LukLed
And one more. Using `with` is great feature of Delphi:) Specially `with TSomething.Create do try finally Free; end;`. At least when there is no `var` like .NET and garbage collector.
LukLed
`with`'s scoping issues alone make it scary. Finding a hairy multi-variable `with` block that spans a few thousand lines of code is a traumatic experience. :-) But `with` is a flame war for a different place.Beyond what I already mentioned, I don't see any major problems with your code that would prevent it from working across systems.
afrazier
+1  A: 

The attribute value is an OleVariant as you say, of the type OleString, and that's an WideString. You've got an "Delphi-7" tag so I assume string is an AnsiString.

When you assign the attribute and when you read it back you get a conversion from AnsiString to Utf16 unicode and back: you might want to consider doing the conversion from code so you can specifiy the CodePage used for conversions. If you don't specify a code page and the reading and writing happens on machines with different CodePages then there's a chance to loose some data (the implicit conversion is done with the system's default code page).

Take a look at:

MultiByteToWideChar
WideCharToMultiByte

those two functions can do the conversion using a given code page.

Cosmin Prund
OK. If codepage during saving is different than codepage during loading, there will be problem with `edSomeTextBox.Text := ChildNodes[I].Attributes['Text']`. Thanks for noticing.
LukLed
No, there won't be any problems. I have to use user default code page, because it is used for display. WideString doesn't depend on code page, so there is no danger.
LukLed