Mielofon
Mielofon

Reputation: 428

How to create OleVariant compatible class in Delphi?

Delphi 2006. XML Data Binding. Generate this class:


type
  IXMLItem = interface(IXMLNode)  
    ['{10B9A877-A975-4FC7-B9EF-448197FA1B90}']  
    { Property Accessors }
    function Get_PartNum: TPartNum_Sku;
    procedure Set_PartNum(Value: TPartNum_Sku);
    { Methods & Properties }
    property PartNum: TPartNum_Sku read Get_PartNum write Set_PartNum;
  end;

  { TXMLItem }

  TXMLItem = class(TXMLNode, IXMLItem)
  protected
    { IXMLItem }
    function Get_PartNum: TPartNum_Sku;
    procedure Set_PartNum(Value: TPartNum_Sku);
  end;
...
function TXMLItem.Get_PartNum: TPartNum_Sku;
begin
  Result := AttributeNodes['partNum'].NodeValue;
end;

procedure TXMLItem.Set_PartNum(Value: TPartNum_Sku);
begin
  SetAttribute('partNum', Value);
end;

How to create OleVariant compatible class TPartNum_Sku? So what would the code:

Result := AttributeNodes['partNum'].NodeValue;

translated without error

[Pascal Error] ipo1.pas(394): E2010 Incompatible types: 'TPartNum_Sku' and 'OleVariant'

Upvotes: 0

Views: 1614

Answers (1)

Rob Kennedy
Rob Kennedy

Reputation: 163277

You're reading the value of an XML attribute, and you're trying to assign it to something of type TPartNum_Sku. The compile-time type of the attribute value is OleVariant, but since XML attributes are always strings, the run-time type of the value stored in that OleVariant will always be WideString. It will never hold a value of type TPartNum_Sku, so your goal of defining that class to be compatible with OleVariant is misguided because they don't need to be compatible. (Just because that's what the compiler says the problem is doesn't mean that's how you need to fix it. The compiler sometimes says "semicolon expected," but it rarely means you should add a semicolon right there.)

The entire point of having your Get_PartNum function is so that you can convert the string attribute value into a TPartNum_Sku object. If TPartNum_Sku is a class, you could call its constructor:

Result := TPartNum_Sku.Create(AttributeNodes['partNum'].NodeValue);

Beware, though, that when you do that, the caller of Get_PartNum is responsible for freeing that object.

If your type is an enumeration, then your conversion depends on what the attribute value is. If it's the numeric value of the enumeration, then you could use this:

Result := TPartNum_Sku(StrToInt(AttributeNodes['partNum'].NodeValue));

If it's the string name, then you could try this:

Result := TPartNum_Sku(GetEnumValue(TypeInfo(TPartNum_Sku),
                                    AttributeNodes['partNum'].NodeValue);

GetEnumValue is in the TypInfo unit. You could also try IdentToInt, from the Classes unit.

You'll have to write inverse code for your Set_PartNum function, too.

Upvotes: 1

Related Questions