2009-08-25 6 views
2

Je dois juste lire la valeur d'un seul attribut dans un fichier XML en utilisant java. Le XML ressemblerait à quelque chose comme ceci:Trouver la valeur d'un attribut spécifique dans un fichier XML dans java

<behavior name="Fred" version="2.0" ....> 

et j'ai juste besoin de lire la version. Quelqu'un peut-il pointer dans la direction d'une ressource qui me montrerait comment faire cela?

+0

Ceci est un bon exemple pourquoi les choses faciles ne sont pas toujours faciles. Même si la plupart des frameworks Java s'appuient fortement sur XML, les outils disponibles pour traiter XML avec Java sont assez lourds. –

Répondre

3

Vous n'avez pas besoin d'une bibliothèque sophistiquée - les anciennes versions JAXP simples de DOM et XPath sont assez faciles à lire et écrire pour cela. Quoi que vous fassiez, n'utilisez pas une expression régulière.

import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.xpath.XPath; 
import javax.xml.xpath.XPathFactory; 

import org.w3c.dom.Document; 

public class GetVersion { 
    public static void main(String[] args) throws Exception { 
     XPath xpath = XPathFactory.newInstance().newXPath(); 
     Document doc = DocumentBuilderFactory.newInstance() 
      .newDocumentBuilder().parse("file:////tmp/whatever.xml"); 
     String version = xpath.evaluate("//behavior/@version", doc); 
     System.out.println(version); 
    } 
} 
1

Voici one.

import javax.xml.parsers.SAXParser; 
import org.xml.sax.helpers.DefaultHandler; 
import org.xml.sax.SAXException; 
import org.xml.sax.Attributes; 
import javax.xml.parsers.SAXParserFactory; 

/** 
* Here is sample of reading attributes of a given XML element. 
*/ 

public class SampleOfReadingAttributes { 
    /** 
    * Application entry point 
    * @param args command-line arguments 
    */ 
    public static void main(String[] args) { 
     try { 
      // creates and returns new instance of SAX-implementation: 
      SAXParserFactory factory = SAXParserFactory.newInstance(); 

      // create SAX-parser... 
      SAXParser parser = factory.newSAXParser(); 
      // .. define our handler: 
      SaxHandler handler = new SaxHandler(); 

      // and parse: 
      parser.parse("sample.xml", handler); 

     } catch (Exception ex) { 
      ex.printStackTrace(System.out); 
     } 
    } 

    /** 
    * Our own implementation of SAX handler reading 
    * a purchase-order data. 
    */ 
    private static final class SaxHandler extends DefaultHandler { 

     // we enter to element 'qName': 
     public void startElement(String uri, String localName, 
       String qName, Attributes attrs) throws SAXException { 

      if (qName.equals("behavior")) { 
       // get version 
       String version = attrs.getValue("version"); 


       System.out.println("Version is " + version); 

      } 
     } 
    } 
} 
+0

J'utiliserais cette approche si j'étais sur JSE5, mais l'API javax.xml.stream dans Java 6 et JEE vous permet de quitter l'analyse après le premier élément sans avoir recours à des mécanismes artificiels comme le lancement d'une exception. – McDowell

+1

Garçon, c'est compliqué. Créer un SAXParserFactory, un SAXParser, et un SaxHandler personnalisé juste pour exécuter "// behavior" est beaucoup de travail. –

0

Si tout ce dont vous avez besoin est de lire la version, alors vous pouvez utiliser regex. Mais vraiment, je pense que vous avez besoin apache digester

+0

XML + regext = appât de flamme :) Mais je suis d'accord avec votre recommandation de digesteur Apache. –

1

Comme mentionné, vous pouvez utiliser le SAXParser. Digesteur mentionné en utilisant des expressions régulières, que je ne recommanderai pas car cela conduirait à un code difficile à maintenir: Que faire si vous ajoutez un autre attribut de version dans une autre balise, ou une autre balise de comportement? Vous pouvez le gérer, mais ce ne sera pas joli.

Vous pouvez également utiliser XPath, qui est un langage pour interroger xml. C'est ce que je recommanderais.

1

JAXB par souci de concision:

private static String readVersion(File file) { 
    @XmlRootElement class Behavior { 
     @XmlAttribute String version; 
    } 
    return JAXB.unmarshal(file, Behavior.class).version; 
    } 

StAX efficacité:

private static String readVersionEfficient(File file) 
     throws XMLStreamException, IOException { 
    XMLInputFactory inFactory = XMLInputFactory.newInstance(); 
    XMLStreamReader xmlReader = inFactory 
     .createXMLStreamReader(new StreamSource(file)); 
    try { 
     while (xmlReader.hasNext()) { 
     if (xmlReader.next() == XMLStreamConstants.START_ELEMENT) { 
      if (xmlReader.getLocalName().equals("behavior")) { 
      return xmlReader.getAttributeValue(null, "version"); 
      } else { 
      throw new IOException("Invalid file"); 
      } 
     } 
     } 
     throw new IOException("Invalid file"); 
    } finally { 
     xmlReader.close(); 
    } 
    } 
+0

Cette version de JAXB est plutôt dérangeante en termes de frais généraux. :) –

Questions connexes