Я пытаюсь найти некоторые элементы из документа SVG с помощью Batik.Получение конкретных элементов с XPath из SVG с помощью Batik
Это пример 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
.
Я делаю что-то неправильно или это ошибка в Батике?
Это из пространства имен по умолчанию 'XMLNS = "http://www.w3.org/2000/svg"'. Попробуйте зарегистрировать это пространство имен. –
Я нашел это очень полезным, но я не могу заставить его работать. По-видимому, существуют противоречивые версии 'batik' и' xerces'. Какие версии вы используете? – clapas
Для тех, кого это интересует, я, наконец, получил его, используя «org.apache.xpath.XPathAPI» вместо 'org.w3c.dom.xpath.XPathEvaluator' в альтернативной, но аналогичной реализации. Cheers – clapas