Delphi html解析检查元素是否具有属性

Delphi html解析检查元素是否具有属性,delphi,html-parsing,mshtml,Delphi,Html Parsing,Mshtml,我有以下程序: class procedure ParseData(AData: string; var ATextList: TList<string>); var HTMLDoc: OleVariant; HTMLElement: OleVariant; I: Integer; begin HTMLDoc := coHTMLDocument.Create as IHTMLDocument2; HTMLDoc.Write(AData); HTMLDoc.Cl

我有以下程序:

class procedure ParseData(AData: string; var ATextList: TList<string>);
var
  HTMLDoc: OleVariant;
  HTMLElement: OleVariant;
  I: Integer;
begin
  HTMLDoc := coHTMLDocument.Create as IHTMLDocument2;
  HTMLDoc.Write(AData);
  HTMLDoc.Close;

  for I := 0 to HTMLDoc.body.all.length - 1 do
  begin
    HTMLElement := HTMLDoc.body.all.item(I);

    if HTMLElement.hasAttribute('attr1') then
      ATextList.Add(HTMLElement.innerHTML);
  end;
end;
类过程ParseData(AData:string;var-ATextList:TList);
变量
HTMLDoc:油酸变体;
HTMLElement:油酸变体;
I:整数;
开始
HTMLDoc:=coHTMLDocument。创建为IHTMLDocument2;
HTMLDoc.Write(AData);
HTMLDoc.Close;
对于I:=0到HTMLDoc.body.all.length-1 do
开始
HTMLElement:=HTMLDoc.body.all.item(一);
如果HTMLElement.hasAttribute('attr1'),则
Add(HTMLElement.innerHTML);
结束;
结束;

问题是
hasAttribute
不起作用。像
setattribute
innerHTML
tagName
这样的功能和程序运行良好。是否有其他方法可以检查元素是否包含给定的属性

您可以检查特定的命名属性,如下所示:

function HasAttribute(ANode : IHtmlDomNode; const AttrName : String) : Boolean;
var
  Attrs : IHtmlAttributeCollection;
  A : IHtmlDomAttribute;
  V : OleVariant;
  i : Integer;
begin
  Result := ANode.nodeType = 1;
  if not Result then
    Exit;
  Attrs := IDispatch(ANode.Attributes) as IHtmlAttributeCollection;
  for i := 0 to Attrs.length - 1 do begin
    V := i;
    A := IDispatch(Attrs.item(V)) as IHtmlDomAttribute;
    if CompareText(AttrName, A.nodeName) = 0 then
      exit;
  end;
  Result := False;
end;

procedure TForm1.btnTestAttributesClick(Sender: TObject);
var
  D : IHtmlDomNode;
  AttrName : String;
  Msg : String;
begin
  D := IDispatch(WebBrowser1.OleObject.Document.GetElementByID('input1')) as  IHtmlDomNode;
  AttrName := 'attr1';
  if HasAttribute(D, AttrName) then
    Msg := 'Found'
  else
    Msg := 'Not found';
  Memo1.Lines.Add(AttrName + ' : ' + Msg);

  AttrName := 'value';
  if HasAttribute(D, AttrName) then
    Msg := 'Found'
  else
    Msg := 'Not found';
  Memo1.Lines.Add(AttrName + ' : ' + Msg);
end;
我建议使用您自己的HasAttribute函数的原因是,MSHTML解析器对节点的“value”属性有问题,如我在对的回答中所述

使用我提供的HTML:

<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>
您可以测试:

if not VarIsNull(HTMLElement.getAttribute('attr1')) then
  ATextList.Add(HTMLElement.innerHTML);

编辑:

hasAttribute
在接口中实现-它需要IE8及更高版本,在IE7标准模式或IE5(怪癖)模式下不受支持

我导入了
C:\Windows\System32\mshtml.tlb
(使用
tlibimp
工具),该代码可以工作:

if (IDispatch(HTMLElement) as IHTMLElement5).hasAttribute('attr1') then...

@科比克:对不起,我好像在你做你的工作时对这个做了编辑。您是否可以重新应用您的属性?您可以使用XPath仅选择具有该属性的元素:
/*[@attr1]
。然后不需要检查属性是否存在。
if not VarIsNull(HTMLElement.getAttribute('attr1')) then
  ATextList.Add(HTMLElement.innerHTML);
if (IDispatch(HTMLElement) as IHTMLElement5).hasAttribute('attr1') then...