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;
Nie można sprawdzić wariant przeciwko zera, zobacz "Nieprzypisane", "VarIsNull" "VarIsEmpty" itd. W dokumentacji. –
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
możliwy duplikat [XPath w Delphi7?] (Http://stackoverflow.com/questions/517145/xpath-in-delphi7) –