在HTML解析中使用IHTMLDOMAttribute获取Cpp中标记的属性

时间:2013-05-31 09:03:34

标签: c++ html html-parsing mshtml microsoft.mshtml

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

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 个答案:

答案 0 :(得分:3)

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

其他的事情是,如果我是你,我将使用CComPtr代替所有裸com指针。

答案 1 :(得分: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

答案 2 :(得分:2)

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


MSHTML文档:

DOM规范:

答案 3 :(得分:2)

检查输入类型,然后查询IID_IHTMLInputElement界面,然后使用get_value