IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Graphisme Java Discussion :

[Batik] Lire un fichier SVG


Sujet :

Graphisme Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 15
    Points : 14
    Points
    14
    Par défaut [Batik] Lire un fichier SVG
    Bonjour à tous,

    J'ai récemment débuté dans l'utilisation de batik pour lire des images svg mais j'ai des soucis pour récupérer à l'intérieur une balise en particulier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    package batik.test;
     
    import java.io.File;
    import java.io.IOException;
     
    import javax.xml.xpath.XPathExpressionException;
     
    import org.apache.batik.dom.AbstractDocument;
    import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
    import org.apache.batik.util.XMLResourceDescriptor;
    import org.w3c.dom.Document;
    import org.w3c.dom.Node;
    import org.w3c.dom.svg.SVGDocument;
    import org.w3c.dom.svg.SVGElement;
    import org.w3c.dom.xpath.XPathResult;
     
    public class CreateDocFromSVGFile {
     
    	public static void main(String[] args) throws XPathExpressionException {
     
    		try {
    		    String parser = XMLResourceDescriptor.getXMLParserClassName();
    		    SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
    		    File file = new File("C://SVGs_input//figure_text.svg");
    		    String uri = file.toURI().toString();
    		    Document doc = f.createDocument(uri);
    		    SVGDocument svgDocument = f.createSVGDocument(uri);
     
    		    AbstractDocument ab = (AbstractDocument) svgDocument;
    		    XPathNSResolver resolver = ab.createNSResolver(ab.getDocumentElement());
    		    XPathResult result = (XPathResult) ab.evaluate("//text", svgDocument.getDocumentElement(), resolver, XPathResult.ANY_TYPE, null);
    		    Node node = result.iterateNext();
    		    while (node != null) {
    		    	System.out.println("<" + node.getNodeName() + "> " + node.getTextContent());
    		    	node = result.iterateNext();
    		    }
     
    		} catch (IOException ex) {
    		    ex.printStackTrace();
    		}
    	}
     
    }
    L'expression "//*" me retourne bien toutes les balises mais dès que j'essaye autre chose de spécifique comme //title ou //text je n'obtiens rien du tout.

    Je sais que le problème vient du namespace par défaut (xmlns:"http://www.w3.org/2000/svg") et j'ai réussi en passant par jdom à obtenir ce que je voulais grâce à l'expression "//svg:text" mais cela ne marche pas avec batik.

    Je mets à disposition le fichier svg que l'on trouve sur la page de présentation de svg sur wikipédia :

    <?xml version="1.0" encoding="utf-8"?>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="300" height="200">
    <title>Exemple simple de figure SVG</title>
    <desc>Cette figure est constituée d'un rectangle, d'un segment de droite et d'un cercle.</desc>

    <rect width="100" height="80" x="0" y="70" fill="green" />
    <line x1="5" y1="5" x2="250" y2="95" stroke="red" />
    <circle cx="90" cy="80" r="50" fill="blue" />
    <text x="180" y="60">Un texte</text>
    <text x="180" y="60">Un autre texte</text>
    </svg>
    Et le résultat avec "//*" en expression :

    svg
    title
    desc
    rect
    line
    circle
    text
    text

    Merci d'avance


    PS : je pense avoir mis ce sujet au mauvais endroit. J'en ai crée un double dans la partie réservée au xml donc si celui-là pouvait être supprimer.

  2. #2
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 15
    Points : 14
    Points
    14
    Par défaut
    Bonjour à tous,

    Bon j'ai fini par trouver tout seul alors je mets la solution ici pour ceux qui pourrait en avoir besoin plus tard.

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    package batik.test;
     
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Iterator;
     
    import javax.xml.namespace.NamespaceContext;
    import javax.xml.xpath.XPath;
    import javax.xml.xpath.XPathConstants;
    import javax.xml.xpath.XPathExpressionException;
    import javax.xml.xpath.XPathFactory;
     
    import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
    import org.apache.batik.util.XMLResourceDescriptor;
    import org.w3c.dom.Document;
    import org.w3c.dom.NodeList;
    import org.w3c.dom.svg.SVGDocument;
     
    public class ParseSVGWithBATIK {
     
    	private static String svgPath = "C://SVGs_input//figure_text.svg";
    	private static String svgNamespaceURI = "http://www.w3.org/2000/svg";
    	private static String newPrefix = "svg";
    	private static String query = "//desc";
     
    	public static void main(String[] args) {
     
    	    String parser = XMLResourceDescriptor.getXMLParserClassName();
    	    SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(parser);
    	    File file = new File(svgPath);
    	    String uri = file.toURI().toString();
    	    SVGDocument svgDocument = null;
    	    try {
    	        svgDocument = factory.createSVGDocument(uri);
    	    } catch (IOException e) {
    		e.printStackTrace();
    	    }
     
    	    NodeList nodes = getNodes(svgDocument);
    	    for (int i = 0; i < nodes.getLength(); i++) {
    	        if (nodes.item(i).getTextContent() != null && !nodes.item(i).getTextContent().isEmpty()) {
    			System.out.println("<" + nodes.item(i).getNodeName() + "> " + nodes.item(i).getTextContent());
    		} else if (nodes.item(i).getNodeValue() != null) {
    			System.out.println("<" + nodes.item(i).getNodeName() + "> " + nodes.item(i).getNodeValue());
    		} else {
    			System.out.println("<" + nodes.item(i).getNodeName() + ">");
    	        }
    	    }
    	}
     
    	/**
             * Executes XPath query over the SVG document.
             */
    	private static NodeList getNodes(Document document) {
    	    if (document != null) {
    	        try {
    		    return (NodeList) getXPath(document).evaluate(modifiedQuery(), document.getDocumentElement(), XPathConstants.NODESET);
    		} catch (XPathExpressionException e) {
    				throw new RuntimeException(e);
    		}
    	    }
    	    return null;
    	}
     
    	private static XPath getXPath(Document document) {
    		XPath xpath = XPathFactory.newInstance().newXPath();
    		xpath.setNamespaceContext(new NamespaceContext() {
    		    @Override
    		    public String getNamespaceURI(String prefix) {
    		        if (prefix.equals(newPrefix)) {
    			    return svgNamespaceURI;
    			}
    			return null;
    		    }
     
    		    @Override
    		    public String getPrefix(String namespaceURI) {
    			if (namespaceURI.equals(svgNamespaceURI)) {
    			    return newPrefix;
    			}
    			return null;
    		    }
     
    	            @Override
    		    public Iterator<?> getPrefixes(String namespaceURI) {
    			ArrayList<String> list = new ArrayList<String>();
    		        if (namespaceURI.equals(svgNamespaceURI)) {
    			    list.add(newPrefix);
    			}
    			return list.iterator();
    		    }
    		});
    		return xpath;
    	}
     
    	private static String modifiedQuery() {
    	    String doubleSlash = query.substring(0, 2);
    	    String tagName = query.substring(2, query.length());
                return doubleSlash + newPrefix + ":" + tagName;
    	}
     
    }

    Avec le résultat :

    <desc> Cette figure est constituée d'un rectangle, d'un segment de droite et d'un cercle.
    Je n'ai pas réussi à passer par la classe AbstractDocument de Batik, ça me trouve rien sauf quand je les retourne tous (//*). Je suis donc passé par la classe NamespaceContent qui sert a récupérer le prefix ou le NamespaceURI en fonction des besoins.
    Les déclarations de string en privé et la méthode modifiedQuery() sont pas vraiment nécessaires, c'était juste pour pas les avoir en dur.

    Y'a d'autres méthodes pour obtenir le même résultat, j'ai trouvé notamment ce lien très utile : http://www.edankert.com/defaultnamespaces.html


    Sur ce, bonne journée et bon code !

    FuRiOuZ

  3. #3
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Accessoirement, sans devoir jouer avec les namespaces, l'expression suivante marchait aussi directement avec le xpath sortant de la factory:

    //*[namespace-uri() = 'http://www.w3.org/2000/svg' and local-name()='desc']


    Mais bon, c'est plus verbeux au niveau de l'expression

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. batik : lire un fichier svg
    Par FuRiOuZ dans le forum APIs
    Réponses: 2
    Dernier message: 18/09/2013, 21h12
  2. [MFC] lire un fichier en int
    Par Kevgeii dans le forum MFC
    Réponses: 3
    Dernier message: 23/01/2004, 10h32
  3. Réponses: 5
    Dernier message: 11/01/2004, 21h17
  4. Lire un fichier de 50 gb
    Par Maryves dans le forum MFC
    Réponses: 2
    Dernier message: 08/01/2004, 15h08
  5. Lire le fichier du port série
    Par saibe dans le forum Linux
    Réponses: 7
    Dernier message: 09/04/2003, 10h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo