2014-09-30 65 views
4

我试图找到与蜡染的SVG文件的一些元素。掌握XPath的特定元素从SVG与蜡染

这是我使用的例子SVG文件:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 

<svg 
    xmlns:svg="http://www.w3.org/2000/svg" 
    xmlns="http://www.w3.org/2000/svg" 
    version="1.0"  
    width="400" 
    height="300" 
    viewBox="0 -100 400 300" 
    preserveAspectRatio="none" 
    id="svg2"> 

    <g id="blubb"> 
    <line x1="0" y1="0" x2="40" y2="120" stroke="red" stroke-width="3"/> 
    <text class="hurz" x="50" y="150">HURZ!</text> 
    </g> 
</svg> 

我试图找到所有text元素与类属性hurz

这是一个例子代码:

import java.awt.*; 
import java.io.*; 
import javax.swing.*; 
import org.apache.batik.swing.*; 
import org.apache.batik.swing.gvt.*; 
import org.w3c.dom.*; 
import org.w3c.dom.svg.*; 
import org.w3c.dom.xpath.*; 

public class XPathTest extends JFrame { 
    private final JSVGCanvas c= new JSVGCanvas(); 


    public XPathTest(){ 
    this.setLayout(new GridLayout()); 
    this.add(c); 

    c.setURI(new File("/tmp/bla.svg").toURI().toString()); 

    c.addGVTTreeRendererListener(new GVTTreeRendererAdapter() { 
     @Override 
     public void gvtRenderingCompleted(GVTTreeRendererEvent e) { 
     testXPath(); 
     } 
    }); 
    } 

    private void testXPath() { 
    final SVGDocument document= c.getSVGDocument(); 
    final XPathEvaluator xpathEvaluator= (XPathEvaluator) document; 
    final SVGElement searchRoot= (SVGElement) document.getElementById("blubb"); 

    //works 
    final XPathResult result1= (XPathResult) xpathEvaluator.evaluate(".//*[@class=\"hurz\"]", searchRoot, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); 
    printResults(result1); 

    //doesn't work                                
    final XPathResult result2= (XPathResult) xpathEvaluator.evaluate(".//text[@class=\"hurz\"]", searchRoot, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); 
    printResults(result2); 

    //doesn't work 
    final XPathResult result3= (XPathResult) xpathEvaluator.evaluate(".//text", searchRoot, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); 
    printResults(result3); 
    } 

    private void printResults(XPathResult result){ 
    int count= 0; 

    Node node; 
    while ((node= result.iterateNext()) != null) { 
     count++; 
    } 

    System.out.println(count); 
    } 

    public static void main(String[] args){ 
    final XPathTest f= new XPathTest(); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    f.setSize(800, 600); 
    f.setVisible(true); 
    } 
} 

当运行此,输出是:

1 
0 
0 

所以很明显的XPath表达式.//*[@class="hurz"]找到正确的节点。但是,当我搜索特定元素类型(在本例中为text元素)时,它找不到与表达式.//text[@class="hurz"].//text一样的内容。

我做得不对或这是蜡染的错误吗?

+0

这是因为默认命名空间'xmlns =“http://www.w3.org/2000/svg”'。尝试注册该名称空间。 – 2014-09-30 07:45:42

+0

我发现这非常有用,但我无法使它工作。显然有'batik'和'xerces'的版本相冲突。你使用什么版本? – clapas 2015-07-08 11:06:12

+1

对于那些感兴趣的人,我终于可以通过使用'org.apache.xpath.XPathAPI'来代替'org.w3c.dom.xpath.XPathEvaluator',但是在另一个类似的实现中。欢呼声 – clapas 2015-07-08 11:35:50

回答

2

这是因为默认的命名空间xmlns="http://www.w3.org/2000/svg"的。尝试使用local-name()函数:

.//*[local-name()=\"text\" and @class=\"hurz\"] 
+0

这是有效的,但它是一个相当丑陋的语法。没有其他办法吗? “注册命名空间”是什么意思?我可以为XPathEvaluator设置默认名称空间吗?我认为这是XPathNSResolver的用途,但我不明白如何使用它。 – radlan 2014-09-30 11:38:17