如何用qt解析xml?

时间:2013-05-13 00:14:42

标签: c++ html xml qt

我正在尝试使用qt解析带有qt的html页面,其中包含:

query.setFocus(qNetworkReply->readAll());  

但是我收到以下错误消息:

Error FODC0002 in tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:u, 
 at line 3, column 44: Entity 'ndash' not declared.

我认为这意味着我试图阅读的html页面格式不正确。如何修复页面?

2 个答案:

答案 0 :(得分:0)

首先可以检查是否在xml中声明了ndash:

<!ENTITY ndash "&#8211;"> <!-- en dash, U+2013 ISOpub --> 
<!ENTITY mdash "&#8212;"> <!-- em dash, U+2014 ISOpub --> 

当您谈论“实体”时,您通常会引用命名实体(也称为XML规范中的内部实体)。您可以在DTD或内部子集中声明它们(即,作为文档中语句的一部分),并在文档中将它们用作引用。在XML文档解析期间,实体引用由其表示替换。 简单来说,这些实体只是处理文档时扩展的宏。

示例:

<!DOCTYPE article PUBLIC "-//NLM//DTD Journal
Publishing DTD v3.0 20080202//EN" "journalpublishing3.dtd"
[<!ENTITY ndash "&#x2013;">]

see here for more info

如果一切正常,那么或者尝试别的:你可以使用内置的QtWebKit。 例如:

class MyPageLoader : public QObject
{
  Q_OBJECT

public:
  MyPageLoader();
  void loadPage(const QUrl&);

public slots:
  void replyFinished(bool);

private:
  QWebView* m_view;
};

MyPageLoader::MyPageLoader()
{
  m_view = new QWebView();

  connect(m_view, SIGNAL(loadFinished(bool)),
          this, SLOT(replyFinished(bool)));
}

void MyPageLoader::loadPage(const QUrl& url)
{
  m_view->load(url);
}

void MyPageLoader::replyFinished(bool ok)
{
  QWebElementCollection elements = m_view->page()->mainFrame()->findAllElements("a");

  foreach (QWebElement e, elements) {
    // Process element e
  }
}

使用班级

MyPageLoader loader;
loader.loadPage("http://www.google.com")

您还可以找到一些包装here

检索元素:

QWebView* view = new QWebView(parent);
view.load(QUrl("http://www.your_site.com"));
QWebElementCollection elements = view.page().mainFrame().findAllElements("a");

答案 1 :(得分:0)

请注意,有关XSLT 2.0的Qt文档明确指出只支持XML实体。

  

XPath数据模型的QtXmlPatterns实现不包含实体(由于QXmlStreamReader没有报告它们)。这意味着函数unparsed-entity-uri()和unparsed-entity-public-id()总是返回负值。

来源:http://doc.qt.io/qt-4.8/xmlprocessing.html#xslt-2-0

他们没有指定方法来修复&#34; (四处走动)这个问题。解决问题的一种方法是将文档作为字符串读取,并将所有HTML实体替换为十六进制语法,甚至替换为相应的Unicode字符,这样解析器就会很高兴。

这是一个缓慢的方法,但要证明这一点:

doc.replace("&ndash;", QChar(8211));

更好的方法是在某处定义实体,但我不确定是否真的有办法实现这一点。

请注意,QXmlStreamReader本身具有设置实体解析程序的功能,但我认为您无法访问该类。因此关于QtXmlPatterns的评论不支持实体。