Checking whether there are <input> object attribute values in the HTML Code using Delphi
Asked Answered
B

1

6

How do I check whether there are input object attribute values in HTML Code using Delphi?

there isn't value attribute.
<input name="input1" type="text"/>
there is value attribute.
<input name="input1" type="text" value=""/>

I've tried the following

  if WebBrowser1.OleObject.Document.GetElementByID('input1').getAttribute('value')<>nil then
       ShowMessage('value attribute is available')
     else
       ShowMessage('value attribute isn"t available')
Berar answered 17/4, 2012 at 8:29 Comment(3)
You can't check a variant against nil, see 'Unassigned', 'VarIsNull' 'VarIsEmpty' etc. in the documentation.Aa
It's more complicated. As kobik pointed in our discussion, you will have to check the value attribute value (sounds silly I know :-), but there's a problem with the value 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 the value attribute exists in a common way. If the value attribute has a non-empty value it remains there of course, but it seems to be not what you are asking.Boisterous
possible duplicate of XPath in Delphi7?Gomes
C
0

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;
Cultigen answered 27/7, 2014 at 15:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.