2013-05-13 111 views
1

我试图解析使用QtXmlQuery使用Qt html页面,用:如何用qt解析xml?

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

,但我收到以下错误信息:

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

我认为,这意味着在HTML页面我试图阅读是畸形的。如何修复该页面?

+3

你的问题是,HTML不是XML。你需要一个HTML解析器。 – Blender 2013-05-13 00:18:41

+0

那么我可以使用哪些工具?也许我可以使用一个工具尽可能地将html转换为xhtml,然后使用xml工具,或者我应该使用不同的东西?这似乎是一个简单的标题错误xml问题,但这个ndash从哪里来,以及如何解决这个问题? – shkra19 2013-05-13 00:22:51

回答

0

第一说不定检查ndash的是在XML中声明:“实体”

<!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

如果一切OK,然后或者尝试其他的东西:你可以使用内建的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") 

你也可以找到一些wraper here

检索元素:

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

如果我已经有了QByteArray中的html,可以跳过所有这些步骤吗?它似乎是一个相当大的代码量。另外,如何使用Xpath检索页面的一部分,这正是我在寻找的第一步?我试图设置一个QXmlQuery,但是当我尝试设置它的焦点时,我遇到了我提到的错误。也许我可以稍微改变页面来使setFocus工作? – shkra19 2013-05-13 00:34:39

+0

以及我不确定,这是一种可以加载页面的方式,请参阅编辑如何检索元素 – 4pie0 2013-05-13 00:49:37

+0

看起来很有趣,但是将其插入到我自己的代码中有很多重构。我确信有一种方法可以将我们的解决方案结合起来,但我并不了解QWebView。但findAllElements真的可以用于任何复杂的xpath吗? – shkra19 2013-05-13 00:54:21

0

注意有关XSLT的Qt文档2.0明确表示只支持XML实体。

The QtXmlPatterns implementation of the XPath Data Model does not include entities (due to QXmlStreamReader not reporting them). This means that functions unparsed-entity-uri() and unparsed-entity-public-id() always return negatively.

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

他们没有指定的方式来 “修复”(四处)的问题。解决此问题的一种方法是将文档作为字符串读取,并将所有HTML实体替换为十六进制语法,甚至用相应的Unicode字符替换,这样解析器就会很快乐。

一个缓慢的方式做到这一点,但为了证明这一点:

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

一个更好的办法是有地方定义的实体,但我不那么肯定有一个真正的方式做那。

请注意,QXmlStreamReader本身有一个函数来设置实体解析器,但我不认为你曾经有权访问该类。因此有关QtXmlPatterns不支持实体的评论。