2013-10-05 70 views
1

我試圖訪問使用WebKitGtk的SVG文件的元素,但我失敗了。該計劃是在瓦拉,這是非常簡單,只是在得到數據從幾個元素的嘗試:使用WebKit與SVG DOM配合工作

using Gtk; 
using WebKit; 

public class WebKitTest : Window { 

    private WebView web_view; 
    private const string uri = "file:///tmp/test.svg"; 

    public WebKitTest() { 
     set_default_size (800, 600); 
     web_view = new WebView(); 
     var scrolled_window = new ScrolledWindow (null, null); 
     scrolled_window.set_policy (PolicyType.AUTOMATIC, PolicyType.AUTOMATIC); 
     scrolled_window.add (this.web_view); 
     var vbox = new VBox (false, 0); 
     vbox.add (scrolled_window); 
     add (vbox); 

     this.destroy.connect (Gtk.main_quit); 

     show_all(); 
     this.web_view.load_uri (WebKitTest.uri); 
     var dom = web_view.get_dom_document(); 
     var el = dom.get_document_element(); 
     var child = el.first_element_child; 
     stdout.printf ("%s\n", child.tag_name); 

     var list = dom.get_elements_by_tag_name ("svg"); 
     stdout.printf ("%lu\n", list.length); 
     assert (list == null); 

     var length = list.length; 
     assert (length == 0); 

     var svg = list.item (0); 
     var res = dom.evaluate ("//path", svg, null, 0, null); 
     DOMNode node; 
     while ((node = res.iterate_next()) != null) { 
      stdout.printf ("%s\n", (node as DOMElement).tag_name); 
     } 
    } 

    public static void main (string[] args) { 
     Gtk.init (ref args); 
     var test = new WebKitTest(); 
     Gtk.main(); 
     return 0; 
    } 
} 

這將編譯與華劣克--pkg webkitgtk-3.0 --pkg GTK + -3.0 webkittest.vala但如果你只安裝了Gtk3,就像我不幸需要將webkit-1.0 .vapi和.deps文件複製到新的webkitgtk-3.0中,並替換gdk-2.0和gtk-2.0中的事件。 deps文件分別爲gdk-3.0和gtk-3.0。

我認爲使用DOM訪問SVG的子元素會很簡單,但只要此代碼獲取到child.tag_name的print語句,它就會給出「HEAD」,並且在文件中找不到任何地方。我正在加載的文件應該是非常標準的,因爲我使用了Inkscape來製作它。

WebKit會做一些有趣的事情,我沒有看到它加載的文檔嗎?

謝謝。

更新:

它肯定似乎WebKit的一切都加載到HTML文檔,因爲當我使用的GObject檢索類型並打印通過get_elements_by_tag_name(「身體」)我得到WebKitDOMHTMLBodyElement返回的節點。即使如此,因爲它可能我試圖做的DOM文檔

var nsres = dom.create_ns_resolver (body); 
DOMXPathResult res = null; 
try { 
    res = dom.evaluate ("//*", body, nsres, 0, null); 
} catch (Error e) { 
    stderr.printf ("%s\n", e.message); 
} 

DOMNode node; 
try { 
    while ((node = res.iterate_next()) != null) { 
     stdout.printf ("%s\n", (node as DOMElement).tag_name); 
    } 
} catch (Error e) { 
    stderr.printf ("%s\n", e.message); 
} 

下面的XPath查詢和我得到的輸出是

HTML 
HEAD 
BODY 

我現在迷路了。 SVG文件可以正確加載,但它不是文檔的一部分?

回答

0

我相信Webkit有一個怪癖,如果它不知道文檔的MIME類型,它會將其包裝在<html>標籤中。所以我懷疑你試圖訪問的文檔轉化了的Webkit成類似:

<html> 
    <head /> 
    <body> 
    <svg>...etc...</svg> 
    </body> 
</html> 

這就是爲什麼你看到在你的代碼中的<head>標籤。

作爲一個建議,嘗試使用Vala的getElementsByTagName()等價物來找到您的<svg>標記。從快速瀏覽一下文檔,它應該是這樣的:

var dom = web_view.get_dom_document(); 
    var el = dom.get_elements_by_tag_name("svg").item(0); 
    var child = var child = el.first_element_child; 

或者,如果有一種方法來告訴的WebKit/WebFrame的MIME類型的文件是「圖像/ SVG + XML」,然後這也應該可以解決你的問題。

+0

謝謝,我不知道WebKit做到了這一點,它很好奇,但它不會識別SVG文檔的MIME類型。你的建議仍然不會返回任何東西,所以我會繼續玩。 –

+1

如果文件是從Web服務器獲取的,它將(或應該)獲得MIME類型。這是因爲它來自HTTP頭。但是你通常不會使用來自文件系統的文件。 –