2012-04-17 9 views
6

Jak sprawdzić, czy istnieją wartości atrybutów obiektu wejściowego w kodzie HTML przy użyciu Delphi?Sprawdzanie, czy istnieją wartości atrybutów obiektu <input> w kodzie HTML przy użyciu Delphi

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

Próbowałem następujących

if WebBrowser1.OleObject.Document.GetElementByID('input1').getAttribute('value')<>nil then 
     ShowMessage('value attribute is available') 
    else 
     ShowMessage('value attribute isn"t available') 
+5

Nie można sprawdzić wariant przeciwko zera, zobacz "Nieprzypisane", "VarIsNull" "VarIsEmpty" itd. W dokumentacji. –

+3

To bardziej skomplikowane. Jak [kobik] (http://stackoverflow.com/users/937125/kobik) wskazał w naszej dyskusji, będziesz musiał sprawdzić wartość atrybutu 'value' (brzmi głupio, wiem :-), ale jest * problem * z atrybutem 'value', ponieważ parser DOM usuwa go, gdy jest pusty, więc z tego' 'parser robi to' "w ten sposób nie można po prostu sprawdzić, czy atrybut" value "istnieje w zwykły sposób. Jeśli atrybut "value" ma niepustą wartość, pozostaje tam oczywiście, ale wydaje się, że nie jest tym, o co prosisz. – TLama

+0

możliwy duplikat [XPath w Delphi7?] (Http://stackoverflow.com/questions/517145/xpath-in-delphi7) –

Odpowiedz

0

Myślałem, że będę tego znosić jako odpowiedź jako zajęło mi trochę czasu, aby ułożyła jakiś kod, aby zbadać, co się mówi w komentuje q, i pomyślałem, że równie dobrze mogę podzielić się tym wysiłkiem i wynikami, które nie były tym, czego oczekiwałem.

Z wyników poniżej nie wynika, że ​​nie można stwierdzić, czy znacznik wejściowy ma atrybut "value" z DOM MSHTML, ponieważ DOM "syntetyzuje", jeśli nie jest fizycznie obecny w źródle HTML. Nie jestem pewien, czy taka była odpowiedź, na którą liczył OP, ale przynajmniej zaoszczędziłoby ci kłopotu z wstawieniem nowego węzła atrybutu, gdybyś chciał ustawić wartość "elementu" elementu wejściowego w kodzie. Jeśli masz, naprawdę musisz wiedzieć, czy wartość atrybutu jest obecna w źródle, które było oryginalnym q, to ​​potrzebujesz innego parsera, ewentualnie wyprowadzonego z domu - może parsera XML, jeśli format strony jest zgodny z XML.

Poniższy przykład pokazuje, że raport DOM: a) istnieje atrybut wartości, nawet jeśli nie ma go w źródłowym kodzie HTML (Input1); b) atrybut o nazwie "wartość", nawet gdy jego wartość węzła jest pusta (Input2); i że c) Wejścia 1 i wejście 2 są nie do odróżnienia od siebie na podstawie zasady zastosowanej w procedurze DumpNode.

Biorąc HTML w tym częściowego 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>') 

Kod poniżej sprawozdaniach:

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< 

Kod:

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;