最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Is Delphi XML binding really not allowing to read a ""-valued attribute? - Stack Overflow

programmeradmin4浏览0评论

I have XML stanza:

<Parameter Name="report_code" Value=""/>

with (automatically generated) Delphi XML binding:

  TXMLParameterType = class(TXMLNode, IXMLParameterType)
  protected
    { IXMLParameterType }
    function Get_Name: WideString;
    function Get_Value: WideString;
    procedure Set_Name(Value: WideString);
    procedure Set_Value(Value: WideString);
  end;
    
function TXMLParameterType.Get_Name: WideString;
begin
  Result := AttributeNodes['Name'].Text;
end;
    
procedure TXMLParameterType.Set_Name(Value: WideString);
begin
  SetAttribute('Name', Value);
end;
    
function TXMLParameterType.Get_Value: WideString;
begin
  Result := AttributeNodes['Value'].NodeValue;
end;
    
procedure TXMLParameterType.Set_Value(Value: WideString);
begin
  SetAttribute('Value', Value);
end;

And I see in XMLDoc.pas that the NodeValue getter does this:

function TXMLNode.GetNodeValue: OleVariant;
begin
  Result := GetText;
  if Result = '' then
    Result := Null;
end;

That results in an error for my business code:

if Param.HasAttribute('Value') then
  Result := Param.Value;

This is beyond comprehension - if there is a ""-valued attribute Value, then one should really be able to read this "" value.

Can't this behavior be configured in Delphi (judging from the Delphi XML code - no)? Is it standard XML behavior?

I checked and such Delphi XMLDoc code was present both in the older (Delphi 2009) and more recent (Delphi XE 11) versions.

I have XML stanza:

<Parameter Name="report_code" Value=""/>

with (automatically generated) Delphi XML binding:

  TXMLParameterType = class(TXMLNode, IXMLParameterType)
  protected
    { IXMLParameterType }
    function Get_Name: WideString;
    function Get_Value: WideString;
    procedure Set_Name(Value: WideString);
    procedure Set_Value(Value: WideString);
  end;
    
function TXMLParameterType.Get_Name: WideString;
begin
  Result := AttributeNodes['Name'].Text;
end;
    
procedure TXMLParameterType.Set_Name(Value: WideString);
begin
  SetAttribute('Name', Value);
end;
    
function TXMLParameterType.Get_Value: WideString;
begin
  Result := AttributeNodes['Value'].NodeValue;
end;
    
procedure TXMLParameterType.Set_Value(Value: WideString);
begin
  SetAttribute('Value', Value);
end;

And I see in XMLDoc.pas that the NodeValue getter does this:

function TXMLNode.GetNodeValue: OleVariant;
begin
  Result := GetText;
  if Result = '' then
    Result := Null;
end;

That results in an error for my business code:

if Param.HasAttribute('Value') then
  Result := Param.Value;

This is beyond comprehension - if there is a ""-valued attribute Value, then one should really be able to read this "" value.

Can't this behavior be configured in Delphi (judging from the Delphi XML code - no)? Is it standard XML behavior?

I checked and such Delphi XMLDoc code was present both in the older (Delphi 2009) and more recent (Delphi XE 11) versions.

Share Improve this question edited Mar 26 at 19:14 Remy Lebeau 601k36 gold badges507 silver badges851 bronze badges asked Mar 26 at 8:55 TomRTomR 3,2366 gold badges43 silver badges108 bronze badges 5
  • 2 I don't see the issue, just check with VarIsNull? – whosrdaddy Commented Mar 26 at 10:02
  • 1 It may be related to the fact that in the W3C DOM interface, Element.getAttribute() doesn't distinguish between an empty attribute and an absent attribute - one of the many poor design choices in the DOM API. – Michael Kay Commented Mar 26 at 10:08
  • 2 @MichaelKay Delphi strings don't make that distinction, either. There is no way to differentiate a string with no value from a string with an empty value. – Remy Lebeau Commented Mar 26 at 17:00
  • 1 @RemyLebeau Yes. But one can achieve a distinction if there would be something like function GetAttribute( var: String ): Boolean to check the function's result for attribute existence. One isn't bound to String's abilities alone. – AmigoJack Commented Mar 26 at 18:58
  • 3 @whosrdaddy or VarToStr(), which returns an empty string for a null variant. – Remy Lebeau Commented Mar 26 at 19:15
Add a comment  | 

1 Answer 1

Reset to default 3

As you noted, the NodeValue property getter will return a Null variant if the value is empty. You can use VarToWideStr() to account for that, which will return an empty string if the variant is Null, eg:

uses
  ..., System.Variants;

function TXMLParameterType.Get_Value: WideString;
begin
  Result := VarToWideStr(AttributeNodes['Value'].NodeValue);
end;
发布评论

评论列表(0)

  1. 暂无评论