2013-10-05 29 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头。但是你通常不会使用来自文件系统的文件。 –