I thought that I'd put this up as an answer as it took me a while to put together some code to investigate what is said in the comments to the q, and I thought I might as well share that effort and the results, which were not what I'd been expecting.
It seems from the results below that you can't tell whether or not an input tag has a "value" attribute from the MSHTML DOM because the DOM "synthesizes" one if it's not physically present in the HTML source. Not sure if that was the answer the OP was hoping for, but at least it would save you the trouble of inserting a new attribute node if you were wanting
to set the Input element's "value" in code. If otoh, you really need to know whether a value
attribute is present in the source, which was the original q, then you need another parser, possibly home-rolled - maybe an XML parser if the page's format is XML-compliant.
The sample below shows that the DOM reports: a) the existence of a value attribute even when none is present in the source HTML (Input1); b) an attribute named 'value' even when its node value is empty (Input2); and that c) Input1 and Input2 are indistinguishable from one another on the
basis applied in the DumpNode routine.
Given the HTML in this partial DFM:
object moHtml: TMemo
[...]
Lines.Strings = (
'<html>'
' <body>'
' <p>This has no value attribute.'
' <input name="input1" type="text"/>'
' <p>This has an empty value attribute.'
' <input name="input2" type="text" value=""/>'
' <p>This has a value attribute.'
' <input name="input3" type="text" value="already has a value"' +
'/>'
' </body>'
'</html>')
The code below reports:
Node name: INPUT
value:
147: type: >text<
158: value: ><
160: name: >input1<
Node name: INPUT
value:
147: type: >text<
158: value: ><
160: name: >input2<
Node name: INPUT
value:
147: type: >text<
158: value: >already has a value<
160: name: >input3<
Code:
procedure TForm1.DumpItems;
var
E : IHtmlElement;
D : IHtmlDomNode;
procedure DumpNode(ANode : IHtmlDomNode);
var
Attrs : IHtmlAttributeCollection;
A : IHtmlDomAttribute;
V : OleVariant;
i : Integer;
begin
Log('Node name', ANode.nodeName);
V := ANode.nodeValue;
if not VarIsNull(V) and not VarIsEmpty(V) then
Log(' value', V)
else
Log(' value', '');
Attrs := IDispatch(ANode.Attributes) as IHtmlAttributeCollection;
for i := 0 to Attrs.length - 1 do begin
V := i;
A := IDispatch(Attrs.item(V)) as IHtmlDomAttribute;
V := A.nodeValue;
if (CompareText(A.nodeName, 'Name') = 0) or (CompareText(A.nodeName, 'Input') = 0) or (CompareText(A.nodeName, 'Type') = 0) or (CompareText(A.nodeName, 'Value') = 0) then begin
if not VarIsNull(V) and not VarIsEmpty(V) then
Log(' ' + IntToStr(i) + ': ' + A.nodeName, '>' + V + '<')
else
Log(' ' + IntToStr(i) + ': '+ A.nodeName, '')
end;
end;
end;
begin
D := IDispatch(WebBrowser1.OleObject.Document.GetElementByID('input1')) as IHtmlDomNode;
DumpNode(D);
D := IDispatch(WebBrowser1.OleObject.Document.GetElementByID('input2')) as IHtmlDomNode;
DumpNode(D);
D := IDispatch(WebBrowser1.OleObject.Document.GetElementByID('input3')) as IHtmlDomNode;
DumpNode(D);
end;
procedure TForm1.Log(const ALabel, AValue : String);
begin
Memo1.Lines.Add(ALabel + ': ' + AValue);
end;
procedure TForm1.btnLoadClick(Sender: TObject);
var
V : OleVariant;
Doc : IHtmlDocument2;
begin
WebBrowser1.Navigate('about:blank');
Doc := WebBrowser1.Document as IHTMLDocument2;
V := VarArrayCreate([0, 0], varVariant);
V[0] := moHtml.Lines.Text;
Doc.Write(PSafeArray(TVarData(v).VArray));
Doc.Close;
end;
procedure TForm1.btnDumpClick(Sender: TObject);
begin
DumpItems;
end;
value
attribute value (sounds silly I know :-), but there's a problem with thevalue
attribute since DOM parser removes it when it's empty, so from this<input name="input1" type="text" value=""/>
the parser do this<input name="input1" type="text"/>
thus you can't simply check if thevalue
attribute exists in a common way. If thevalue
attribute has a non-empty value it remains there of course, but it seems to be not what you are asking. – Boisterous