4

请帮助我使用 .html 进行 html 解析MSHTML。我获取特定标签所有属性的代码是这样的

void GetAttributes(MSHTML::IHTMLElementPtr pColumnInnerElement)
{
    IHTMLDOMNode *pElemDN = NULL;
    LONG lACLength;
    MSHTML::IHTMLAttributeCollection *pAttrColl;
    IDispatch* pACDisp;
    VARIANT vACIndex;
    IDispatch* pItemDisp;
    IHTMLDOMAttribute* pItem;
    BSTR bstrName;
    VARIANT vValue;
    VARIANT_BOOL vbSpecified;
    pColumnInnerElement->QueryInterface(IID_IHTMLDOMNode, (void**)&pElemDN);
    if (pElemDN != NULL)
    {
        pElemDN->get_attributes(&pACDisp);
        pACDisp->QueryInterface(IID_IHTMLAttributeCollection, (void**)&pAttrColl);
        pAttrColl->get_length(&lACLength);
        vACIndex.vt = VT_I4;
        for (int i = 0; i < lACLength; i++)
        {

            vACIndex.lVal = i;
            pItemDisp = pAttrColl->item(&vACIndex);
            if (pItemDisp != NULL)
            {
               pItemDisp->QueryInterface(IID_IHTMLDOMAttribute, (void**)&pItem);
               pItem->get_specified(&vbSpecified);
               pItem->get_nodeName(&bstrName);
               pItem->get_nodeValue(&vValue);

               if (vbSpecified)
                cout<<_com_util::ConvertBSTRToString(bstrName)<<" :"<<_com_util::ConvertBSTRToString(vValue.bstrVal)<<endl;
               pItem->Release();
            }
            pItemDisp->Release();

        }
        pElemDN->Release();
        pACDisp->Release();
        pAttrColl->Release();
    }
}

问题是对于给定的标签<input id="Switch l_id2" class="pointer" name="Switch" onclick='SetControl("Switch l",1)' type="button" value="OK">,它会打印除属性之外的所有value属性。该get_specified函数正在返回false属性value

我的输出是

id :Switch l_id2
class :pointer
onclick :SetControl("Switch l",1)
type :button
name :Switch

知道为什么吗?还有哪些其他属性可能有这个问题?

笔记

我试过这样。它显示了正确的属性结果value

        if (strcmp(_com_util::ConvertBSTRToString(bstrName), "value") == 0)
        {
            cout<<_com_util::ConvertBSTRToString(bstrName)<<" :"<<_com_util::ConvertBSTRToString(vValue.bstrVal)<<endl;
        }
4

4 回答 4

3

你真的关心指定的标志吗?您说要处理所有属性,我认为如果是这种情况您不需要关心指定的标志,只需处理所有属性即可。

另一件事是,如果我是你,我将使用 CComPtr 来代替所有裸露的 com 指针。

于 2013-06-07T04:14:22.910 回答
3

如果您在托管(CLI)VC++ 中工作,那么您可以考虑通过 nuget 获得的HTML Agility Pack 。

如果不需要坚持 MSHTML,那么您可能可以选择将 HTML 文档解析为 XML 文档。这样,您就可以非常灵活地解析所有标签和属性。有很多可用于 C++ 的 XML 解析器。

这个库看起来简洁高效(适用于多个平台):https://github.com/leethomason/tinyxml2

另一个是:http://pugixml.org/

如果您想摆脱 MSHTML 依赖项,此链接可能会对您有所帮助:http: //www.codeproject.com/Articles/30342/Remove-Microsoft-mshtml-dependency

于 2013-06-07T05:21:33.320 回答
2

检查输入类型,然后查询IID_IHTMLInputElement接口,然后使用get_value.

于 2013-06-07T12:37:28.353 回答
2

我以前从未使用过这个,但根据库文档和 DOM 规范,似乎get_nodeValue()根据“节点对象”的类型会做不同的事情。尝试调用get_nodeValue()get_nodeName()IHTMLDOMNode对象上。很明显,像“value”、“ID”和“Name”这样的一些属性不是 DOM 下属性集合的一部分。


MSHTML 文档:

DOM 规范:

于 2013-06-06T20:03:41.103 回答