ho pensato che avevo messo questo come una risposta come mi c'è voluto un po 'per mettere insieme un po' di codice per indagare su ciò che viene detto nel commenti al q, e ho pensato che potrei anche condividere quello sforzo e i risultati, che non erano quello che mi aspettavo.
Sembra dai risultati seguenti che non è possibile stabilire se un tag di input abbia o meno un attributo "value" dal DOM MSHTML perché il DOM "sintetizza" uno se non è fisicamente presente nell'origine HTML. Non sono sicuro se quella era la risposta sperata dall'OP, ma almeno ti avrebbe risparmiato il problema di inserire un nuovo nodo attributo se volevi che imposti il "valore" dell'elemento Input nel codice. Se otoh, hai davvero bisogno di sapere se un attributo valore è presente nel sorgente, che era il q originale, quindi hai bisogno di un altro parser, possibilmente home-roll - forse un parser XML se il formato della pagina è compatibile con XML.
L'esempio seguente mostra che il DOM riporta: a) l'esistenza di un attributo valore anche quando nessuno è presente nell'HTML di origine (Input1); b) un attributo chiamato 'valore' anche quando il suo valore di nodo è vuoto (Input2); e che c) Input1 e Input2 sono indistinguibili l'uno dall'altro sulla base applicata nella routine DumpNode.
Dato il codice HTML in questo parziale 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>')
Il codice seguente è riportato:
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<
Codice:
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;
Non è possibile controllare una variante contro nullo, vedere 'Non assegnato', 'VarIsNull' 'VarIsEmpty' ecc. Nella documentazione. –
È più complicato. Come [kobik] (http://stackoverflow.com/users/937125/kobik) puntato nella nostra discussione, dovrai controllare il valore di attributo 'value' (suona sciocco lo so :-), ma c'è un problema * * con l'attributo 'value' dato che il parser DOM lo rimuove quando è vuoto, quindi da questo' 'il parser fa questo' 'quindi non puoi semplicemente controllare se l'attributo' value' esiste in un modo comune. Se l'attributo 'value' ha un valore non vuoto, rimane lì ovviamente, ma sembra che non sia quello che stai chiedendo. – TLama
possibile duplicato di [XPath in Delphi7?] (Http://stackoverflow.com/questions/517145/xpath-in-delphi7) –