2014-09-30 3 views
4

바틱이있는 SVG 문서에서 몇 가지 요소를 찾으려고합니다. 내가 클래스 속성 hurz 모든 text 요소를 찾기 위해 노력하고바틱이있는 SVG에서 XPath로 특정 요소 가져 오기

<?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> 

:

내가 사용하고있는 예를 SVG 문서입니다.

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"기본 네임 스페이스입니다. 해당 네임 스페이스를 등록 해보십시오. –

+0

나는 이것을 매우 유용하게 생각했지만 작동하게 만들 수는 없다. 분명히 '바틱 (batik)'과 '커세스 (xerces)'의 상충되는 버전이있다. 어떤 버전을 사용합니까? – clapas

+1

관심이있는 사람들을 위해, 대안이지만 비슷한 구현에서'org.w3c.dom.xpath.XPathEvaluator' 대신'org.apache.xpath.XPathAPI'를 사용하여 마침내 작동하게 만들었습니다. 건배 – clapas

답변

2

기본 네임 스페이스 xmlns="http://www.w3.org/2000/svg" 때문입니다. local-name() 기능을 사용해보십시오 :

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

그게 효과가 있지만 꽤 못생긴 구문입니다. 다른 방법이 없습니까? 네임 스페이스 등록이란 무엇을 의미합니까? XPathEvaluator의 기본 네임 스페이스를 설정할 수 있습니까? 이것이 XPathNSResolver가 무엇인지에 대한 것으로 생각되지만 사용 방법을 이해하지 못합니다. – radlan

관련 문제