2013-05-31 3 views
3

s'il vous plaît aidez-moi je fais une analyse html en utilisant MSHTML. Mon code pour obtenir tous les attributs d'une balise particulière est comme ceDans l'analyse HTML Obtenir les attributs d'une étiquette dans Cpp en utilisant IHTMLDOMAttribute

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(); 
    } 
} 

Le problème est pour la balise donnée <input id="Switch l_id2" class="pointer" name="Switch" onclick='SetControl("Switch l",1)' type="button" value="OK"> elle imprime tous les attributs sauf value attribut. La fonction get_specified renvoie false pour l'attribut value.

Ma sortie est

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

Toute idée pourquoi? Aussi quels autres attributs peuvent avoir ce problème ??

Remarque

J'ai essayé de la sorte. Il montre les bons résultats d'attribut pour value.

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

Que signifie votre note? Est-ce dû au test vbSpecified? –

+0

J'ai ajouté Note pour afficher la valeur correcte dans vValue.bstrVal. Mais encore vbSpecified retourne false – 999k

+0

Je ne suis pas sûr que le drapeau spécifié est toujours significatif. Avez-vous essayé de changer le mode de compatibilité de document (http://msdn.microsoft.com/en-us/library/cc288325.aspx). Par exemple, specified est toujours TRUE quand IE est en IE9 en mode 'Standards'. –

Répondre

3

Si vous travaillez dans VC++ géré (CLI), vous pouvez considérer le HTML Agility Pack, disponible via nuget.

Si vous ne souhaitez pas utiliser MSHTML, vous pouvez probablement opter pour l'analyse des documents HTML en tant que documents XML. De cette façon, vous seriez capable d'analyser tous les tags et attributs avec beaucoup de flexibilité. Il y a beaucoup d'analyseurs XML disponibles pour C++.

Cette bibliothèque semble simple compact et efficace (disponible pour plusieurs plates-formes): https://github.com/leethomason/tinyxml2

Un autre est: http://pugixml.org/

Ce lien peut vous aider si vous voulez vous débarrasser de la dépendance MSHTML: http://www.codeproject.com/Articles/30342/Remove-Microsoft-mshtml-dependency

+1

Merci pour votre temps et votre réponse. Oui je sais qu'il y a tellement d'autres parseurs. Après avoir attendu 2 3 jours et aucune réponse ici, j'ai sélectionné un autre analyseur HTML mentionné dans un autre thread SO – 999k

2

Je ne l'ai jamais travaillé avec cela auparavant, mais selon la bibliothèque docs et spécifications DOM, il semble que get_nodeValue() des choses différentes en fonction ne fait du type de « objet noeud ». Essayez d'appeler get_nodeValue() ou get_nodeName() sur l'objet IHTMLDOMNode. Il semble clair que certaines propriétés comme "value", "ID" et "Name" ne font pas partie de la collection d'attributs sous le DOM.


MSHTML documents:

spécification DOM:

+1

Merci pour votre temps. En fait, get_nodeName() renvoie le nom de la variable, c'est-à-dire INPUT dans mon cas, pas le nom de l'attribut. Et j'ai vérifié presque toutes les interfaces de IHTMLDOMNode également dans mon code. – 999k

+0

Aussi problème n'est pas dans l'interface funtion get_nodeValue(). De ma note, il est clair que cette fonction renvoie la valeur correcte, mais get_specified retourne false même si elle est spécifiée dans la balise – 999k

+0

Désolé, je dois avoir mal compris la question (jamais utilisé cette bibliothèque auparavant). Les deux documents répertoriés dans ma réponse indiquent que l'indicateur spécifié doit être vrai pour l'attribut de valeur. Ceci est une ancienne bibliothèque MS et il peut y avoir des bugs cependant. Je vous recommande de passer à un moteur d'analyse XML plus générique comme cpz suggéré dans sa réponse. – idoby

3

Vous vous souciez vraiment du drapeau de spécifié? Vous avez dit que vous voulez traiter tous les attributs, je pense que si c'est le cas, vous n'avez pas besoin de vous soucier de l'indicateur spécifié, il suffit de traiter tous les attributs.

Autre chose est si j'étais vous, je vais utiliser CComPtr à la place de tout pointeur com nu.

+0

Je ne suis pas très familier avec Visual Studio et d'autres termes avancés en C++ comme CComPtr. Je ne sais pas quels attributs sont présents dans mon tag. Donc, si j'utilise get_nodeValue() withut, je vérifie que son indicateur null retourne le pointeur NULL et même le mauvais pointeur quelques fois. – 999k

2

vérifiez le type d'entrée, puis recherchez l'interface IID_IHTMLInputElement, puis utilisez get_value.

Questions connexes