如何使用QT解析HTML文件?

时间:2018-03-11 18:03:59

标签: html c++ qt

目标是与HTML(而不是XML)文档的内容实现QDomDocument或类似。

问题是某些标签,尤其是script会触发错误:

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript">
        var a = [1,2,3];
        var b = (2<a.length);
    </script>
</head>
<body/>
</html>
  

形式不佳:元素类型&#34; a.length&#34;必须遵循属性规范,&#34;&gt;&#34;或&#34; /&gt;&#34;。

我理解HTML与XML不同,但Qt有解决方案似乎是合理的:

  • 将解析器设置为接受HTML
  • HTML的另一个类
  • 将某些标签名称设置为CDATA的方法。

我目前的尝试只能实现正常的XML解析:

QString mainHtml;

{
    QFile file("main.html");
    if (!file.open(QIODevice::ReadOnly)) qDebug() << "Error reading file main.html";
    QTextStream stream(&file);
    mainHtml = stream.readAll();
    file.close();
}

QQDomDocument doc;
QString errStr;
int errLine=0, errCol=0;
doc.setContent( mainHtml, false, &errStr, &errLine, &errCol);
if (!errStr.isEmpty())
{
    qDebug() << errStr << "L:" << errLine << ":" << errCol;
}

std::function<void(const QDomElement&, int)> printTags=
[&printTags](const QDomElement& elem, int tab)
{
    QString space(3*tab, ' ');
    QDomNode n = elem.firstChild();
    for( ;!n.isNull(); n=n.nextSibling()) 
    {
        QDomElement e = n.toElement();
        if(e.isNull()) continue;

        qDebug() << space + e.tagName(); 
        printTags( e, tab+1);
    }
};
printTags(doc.documentElement(), 0);

注意:我想避免包含完整的webkit。

1 个答案:

答案 0 :(得分:1)

我建议使用htmlcxx。它是在LPGL下许可的。它适用于Linux和Windows。如果您使用带有msys.

的Windows编译

要编译它,只需解压缩文件并运行

./configure --prefix=/usr/local/htmlcxx
make
make install

在.pro文件中添加include和library目录。

INCLUDEPATH += /usr/local/htmlcxx/include
LIBS += -L/usr/local/htmlcxx/lib -lhtmlcxx

使用示例

#include <iostream>
#include "htmlcxx/html/ParserDom.h"
#include <stdlib.h>

int main (int argc, char *argv[])
{
  using namespace std;
  using namespace htmlcxx;

  //Parse some html code
  string html = "<html><body>hey<A href=\"www.bbxyard.com\">myhome</A></body></html>";
  HTML::ParserDom parser;
  tree<HTML::Node> dom = parser.parseTree(html);
  //Print whole DOM tree
  cout << dom << endl;

  //Dump all links in the tree
  tree<HTML::Node>::iterator it = dom.begin();
  tree<HTML::Node>::iterator end = dom.end();
  for (; it != end; ++it)
  {
     if (strcasecmp(it->tagName().c_str(), "A") == 0)
     {
       it->parseAttributes();
       cout << it->attribute("href").second << endl;
     }
  }

  //Dump all text of the document
  it = dom.begin();
  end = dom.end();
  for (; it != end; ++it)
  {
    if ((!it->isTag()) && (!it->isComment()))
    {
      cout << it->text() << " ";
    }
  }
  cout << endl;
  return 0;
}

示例的信用: https://github.com/bbxyard/sdk/blob/master/examples/htmlcxx/htmlcxx-demo.cpp

您无法为HTML使用XML解析器。您可以使用htmlcxx或将HTML转换为有效的XML。然后您可以自由使用QDomDocument,Qt XML解析器等。

QWebEngine还具有解析功能,但会给应用程序带来很大的开销。