2010-11-23 7 views
1

J'ai vu de nombreux exemples sur la façon de lire des fichiers XML en Java. Mais ils ne montrent que des fichiers XML simples. Par exemple, ils montrent comment extraire les noms et prénoms d'un fichier XML. Cependant, j'ai besoin d'extraire des données à partir d'un fichier XML collada. Comme ceci:Comment analyser les fichiers XML avancés en Java

<library_visual_scenes> 
    <visual_scene id="ID1"> 
     <node name="SketchUp"> 
      <instance_geometry url="#ID2"> 
       <bind_material> 
        <technique_common> 
         <instance_material symbol="Material2" target="#ID3"> 
          <bind_vertex_input semantic="UVSET0" input_semantic="TEXCOORD" input_set="0" /> 
         </instance_material> 
        </technique_common> 
       </bind_material> 
      </instance_geometry> 
     </node> 
    </visual_scene> 
</library_visual_scenes> 

Ceci est seulement une petite partie d'un fichier collada. Ici, j'ai besoin d'extraire l'id de visual_scene, puis l'URL de instance_geometry et la cible de instance_material. Bien sûr, j'ai besoin d'extraire beaucoup plus, mais je ne comprends pas comment l'utiliser vraiment et c'est un bon point de départ.

J'ai ce code à ce jour:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
DocumentBuilder builder = null; 
try { 
    builder = factory.newDocumentBuilder(); 
} 
catch(ParserConfigurationException error) { 
    Log.e("Collada", error.getMessage()); return; 
} 
Document document = null; 
try { 
    document = builder.parse(string); 
} 
catch(IOException error) { 
    Log.e("Collada", error.getMessage()); return; 
} 
catch(SAXException error) { 
    Log.e("Collada", error.getMessage()); return; 
} 
NodeList library_visual_scenes = document.getElementsByTagName("library_visual_scenes"); 

Il semble que la plupart des exemples sur le web est similaire à celui-ci: http://www.easywayserver.com/blog/java-how-to-read-xml-file/

J'ai besoin d'aide pour déterminer ce qu'il faut faire quand je veux extraire des balises plus profondes ou trouver un bon tutoriel sur la lecture/l'analyse des fichiers XML.

+2

Je voudrais utiliser 'javax.xml.xpath' si le XML n'est pas très grand, et un filtre d'événements SAX sinon. – khachik

+1

Ou XMLBeans, ou JAXB, ou ... – bmargulies

+0

Jetez un coup d'oeil à: http://www.saxproject.org/quickstart.html – krico

Répondre

4

Vous utilisez DOM dans votre code.
DOM crée une structure arborescente du fichier xml analysé et vous devez parcourir l'arborescence pour obtenir les informations dans divers nœuds.
Dans votre code tout ce que vous avez fait est de créer la représentation de l'arbre. C'est à dire.

document = builder.parse(string);//document is loaded in memory as tree 

Maintenant, vous devriez faire référence à l'API DOM pour voir comment obtenir les informations dont vous avez besoin.Par exemple, cette méthode renvoie une liste de nœuds de tous les éléments avec le nom spécifié. Par exemple, cette méthode renvoie un NodeList de tous les éléments avec le nom spécifié.
Maintenant, vous devriez boucler sur la NodeList

for (int i = 0; i < library_visual_scenes.getLength(); i++) { 
    Element element = (Element) nodes.item(i); 
    Node visual_scene = element.getFirstChild(); 
    if(visual_scene.getNodeType() == Node.ELEMENT_NODE) 
    { 
     String id = ((Element)visual_scene).getAttribute(id); 
     System.out.println("id="+id); 
    } 
} 

AVERTISSEMENT: Ceci est un exemple de code. Je ne l'ai pas compilé. Il vous montre le concept. Vous devriez regarder dans DOM apis.

+0

Je vais donner une chance à DOM. Principalement parce que c'est ainsi que j'ai commencé et ça a l'air facile. J'ai aussi trouvé ce qui ressemble à un bon tutoriel de base: http://www.roseindia.net/xml/dom/ – Espen

6

Vraiment, votre analyse en soi est déjà fait lorsque vous appelez builder.parse(string). Ce que vous devez savoir maintenant, c'est comment sélectionner/interroger les informations du document XML analysé.

Je suis d'accord avec @khachik sur la façon de faire cela. Élaborer un peu (puisque personne d'autre n'a posté de réponse):

XPath est le moyen le plus pratique pour extraire des informations, et si votre document d'entrée n'est pas énorme, XPath est assez rapide. Here est un bon tutoriel de démarrage sur XPath en Java. XPath est également recommandé si vous avez besoin d'un accès aléatoire aux données XML (c'est-à-dire si vous devez extraire les données de l'arborescence dans un ordre différent de celui du document source), car SAX est conçu pour un accès linéaire.

Quelques exemples d'expressions XPath:

  • extraient l'id de visual_scene: /*/visual_scene/@id
  • l'url de instance_geometry: /*/visual_scene/node/instance_geometry/@url
  • l'url de instance_geometry pour le nœud dont le nom est Sketchup: /*/visual_scene/node[@name = 'Sketchup']/instance_geometry/@url
  • la cible de instance_material: /*/visual_scene/node/instance_geometry/bind_material/technique_common/instance_material/@target
Étant donné que les modèles COLLADA peuvent être très volumineux, vous devrez peut-être utiliser un filtre basé sur SAX, qui vous permettra de traiter le document en mode flux sans avoir à le conserver en mémoire en une seule fois. Mais si votre code existant pour analyser le XML fonctionne déjà assez bien, vous n'aurez peut-être pas besoin de SAX. SAX est plus compliqué à utiliser pour extraire des données spécifiques que XPath.

1

EclipseLink JAXB (MOXy) a une extension @XmlPath utile pour tirer parti de XPath pour remplir un objet. C'est peut-être ce que vous cherchez. Note: Je suis le chef de la technologie MOXy.

L'exemple suivant associe un objet simple d'adresse à la représentation de Google de l'information de géocodage:

package blog.geocode; 

import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlType; 

import org.eclipse.persistence.oxm.annotations.XmlPath; 

@XmlRootElement(name="kml") 
@XmlType(propOrder={"country", "state", "city", "street", "postalCode"}) 
public class Address { 

    @XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:SubAdministrativeArea/ns:Locality/ns:Thoroughfare/ns:ThoroughfareName/text()") 
    private String street; 

    @XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:SubAdministrativeArea/ns:Locality/ns:LocalityName/text()") 
    private String city; 

    @XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:AdministrativeAreaName/text()") 
    private String state; 

    @XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:CountryNameCode/text()") 
    private String country; 

    @XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:SubAdministrativeArea/ns:Locality/ns:PostalCode/ns:PostalCodeNumber/text()") 
    private String postalCode; 

} 

Pour le reste de l'exemple voir:

0

De nos jours, plusieurs Les outils RAD Java ont des générateurs de code Java provenant de DTD données, vous pouvez donc les utiliser.