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不支持實體的評論。