1

我正在尝试使用 WebKitGtk 访问 SVG 文件的元素,但我失败了。该程序在 Vala 中,它非常简单,只是尝试从几个元素中获取数据:

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;
    }
}

这与valac --pkg webkitgtk-3.0 --pkg gtk+-3.0 webkittest.vala 一起编译,但如果你像我一样只安装了 Gtk3,不幸的是你需要将 webkit-1.0 .vapi 和 .deps 文件复制到新的 webkitgtk -3.0 和将 .deps 文件中出现的 gdk-2.0 和 gtk-2.0 分别替换为 gdk-3.0 和 gtk-3.0。

我认为使用 DOM 访问 SVG 的子元素会很简单,但是一旦此代码到达 child.tag_name 的 print 语句,它就会给出“HEAD”,并且在文件中找不到任何地方。我正在加载的文件应该是非常标准的,因为我使用了 inkscape 来制作它。

WebKit 是否对它加载的文档做了一些我看不到的有趣的事情?

谢谢。

更新:

WebKit 似乎将所有内容加载到 HTML 文档中,因为当我使用 GObject 检索类型并为 get_elements_by_tag_name("body") 返回的节点打印它时,我得到了 WebKitDOMHTMLBodyElement。尽管如此,我可能尝试在 DOMDocument 上执行以下 XPath 查询

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);
}

我得到的只是输出

HTML
HEAD
BODY

我现在迷路了。SVG 文件清楚地正确加载,但它不是文档的一部分?

4

1 回答 1

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 类型是“image/svg+xml”,那么这也应该可以解决您的问题。

于 2013-10-06T02:12:59.920 回答