2012-07-01 4 views
2

J'essaie d'apprendre l'analyse XML ici et j'ai reçu un code pour commencer. J'ai fait quelques recherches sur les différentes API que j'utilise et j'ai graduellement pu déboguer mon code en quelque chose qui, je l'espère, fonctionnera. J'essaie d'analyser les fichiers XML en câblant durement les requêtes XPath dans une variable de chaîne. J'utilise aussi DocumentBuilderFactory si cela aide du tout. Quoi qu'il en soit, je continue d'obtenir cette exception: Java.lang.String ne peut pas être converti en org.w3c.dom.Node (je l'ai marqué dans le code ci-dessous). Je comprends ce que sont les erreurs. La requête de chaîne ne semble pas être en accord avec les paramètres de la méthode "evaluate". Je ne sais pas comment le réparer. J'ai essayé toutes sortes de moulages différents et ils ne fonctionnent pas. Quelque chose me dit que je fais quelque chose d'horriblement mauvais ici ... aidez s'il vous plaît! PS. Je suis désolé mon code est un désordre, je suis totalement nouveau à l'analyse, je sais aussi qu'il y a des importations inutiles mais je suppose que je pourrais en avoir besoin si je fais quelques changements.Analyse XML avec Java XPath Query, Erreur:

code:

import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.ParserConfigurationException; 
import javax.xml.xpath.XPath; 

import org.jaxen.JaxenException; 
import org.jaxen.dom.DOMXPath; 
import org.w3c.dom.Document; 
import org.w3c.dom.NodeList; 
import org.w3c.dom.Node; 
import org.w3c.dom.Element; 
import org.xml.sax.SAXException; 

import java.io.File; 
import java.io.IOException; 
import java.util.List; 

public class Parser 
{ 
public static void main(String[] args) 
{ 
    boolean isNamespaceAware = true; 
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    dbf.setNamespaceAware(isNamespaceAware); 
    DocumentBuilder builder = null; 
    try 
    { 
     builder = dbf.newDocumentBuilder(); 
    } 
    catch (ParserConfigurationException e2) 
    { 
     e2.printStackTrace(); 
    } 
    try 
    { 
     Document workingDocument = 
builder.parse("C:\\Users\\Brandon\\Job\\XPath\\XPath_Sample_Stuff\\XPath_Objects.xml"); 
    } 
    catch (SAXException e1) 
    { 
     e1.printStackTrace(); 
    } 
    catch (IOException e1) 
    { 
     e1.printStackTrace(); 
    } 
    String xPathQuery = "/book/author"; 
    DOMXPath generatedPath; 
    String results = null; 
    try 
    { 
     generatedPath = new DOMXPath(xPathQuery); 
//Here is the errror 
     results = generatedPath.evaluate(xPathQuery); 
    } 
    catch (JaxenException e) 
    { 
     e.printStackTrace(); 
    } 
    if(results == null) 
     System.err.println("There was an issue processing the xpath, and 
results were still null."); 
    for (int i=0; i<= results.getLength();i++) 
    { 
     System.out.println(results.item(i)); 
    } 
}     

}

Voici quelques XML à partir d'un fichier XML m'a donné:

<?xml version="1.0"?> 
<catalog> 
<book id="bk101"> 
    <author>Gambardella, Matthew</author> 
    <title>XML Developer's Guide</title> 
    <genre>Computer</genre> 
    <price>44.95</price> 
    <publish_date>2000-10-01</publish_date> 
    <description>An in-depth look at creating applications with XML.</description> 
</book> 
+0

Qu'est-ce que Jaxen et DOMXPath? Ceux-ci ne font pas partie du core Java autant que je sache et ne sont généralement pas utilisés avec XPath (encore autant que je sache). Pourquoi ne pas simplement utiliser des classes Java standard pour le faire? –

+0

Aussi, vous voudrez commencer avec un fichier XML relativement simple et publier ce fichier ici avec votre question. –

+0

Ouais, Comme je l'ai dit on m'a donné le code, donc je ne suis pas vraiment sûr de moi-même. J'ai également importé un jar externe de sorte que c'est peut-être d'où DOMXPath est venu. Soupir ... Mais j'essaie d'obtenir le code qui m'a été donné pour travailler, je ne veux pas écrire une nouvelle classe d'analyseur à moins que je doive le faire. –

Répondre

1

L'erreur vous dit que la méthode DOMXPath#evaluate(...) renvoie une chaîne. Vous essayez de le transformer en NodeList, ce qui n'est pas le cas. L'API pour cette méthode va tout expliquer - mais encore une fois, cette API ne fait pas partie de Java standard mais fait plutôt partie de Jaxen. Mais le résultat est logique même pour le noyau Java puisque sa méthode XPath#evaluate(...) aussi habituellement renvoie une chaîne (à l'exception d'une surcharge). Encore une fois, vous ne voulez peut-être pas utiliser Jaxen pour l'instant, à moins d'avoir de bonnes raisons de le faire mais que vous ne nous l'ayez pas encore dit.

Modifier
Dites que vous avez eu un XML dans un fichier, Catalog.xml, qui ressemblait à ceci:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<catalog> 
    <book id="bk101"> 
     <author>Smith, John</author> 
     <title>Fubars Rule</title> 
     <price>100.1</price> 
     <date>2012-10-01</date> 
     <description>A witty exposé</description> 
    </book> 
    <book id="bk102"> 
     <author>Python, Monty</author> 
     <title>Your Hovercraft is full of Eels</title> 
     <price>250.5</price> 
     <date>10-01-01</date> 
     <description>an even wittier exposé</description> 
    </book> 
</catalog> 

JAXB pourrait marshall/unmarshall ce connard avec seulement quelques annotations dans vos classes régulières. Cela rend la chose presque idiote. Par exemple:

import java.io.File; 
import java.util.ArrayList; 
import java.util.List; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlType; 

public class CatalogTest { 
    private static final String PATH_NAME = "Catalog.xml"; 



    public static void main(String[] args) { 
     // comment one of the lines below and un-comment the other to test 
     // marshallTest(); 
     unmarshallTest(); 
    } 



    private static void unmarshallTest() { 
     JAXBContext context; 
     try { 
     context = JAXBContext.newInstance(Catalog.class); 
     Unmarshaller unmarshaller = context.createUnmarshaller(); 
     File catalogFile = new File(PATH_NAME); 
     Catalog catalog = (Catalog) unmarshaller.unmarshal(catalogFile ); 
     System.out.println(catalog); 
     } catch (JAXBException e) { 
     e.printStackTrace(); 
     } 

    } 



    private static void marshallTest() { 
     try { 
     Book[] books = { 
       new Book("bk101", "Smith, John", "Fubars Rule", 100.10, "2012-10-01", "A witty exposé"), 
       new Book("bk102", "Python, Monty", "Your Hovercraft is full of Eels", 250.50, "10-01-01", "an even wittier exposé") 
     }; 
     Catalog catalog = new Catalog(); 
     for (Book book : books) { 
      catalog.addBook(book); 
     } 
     JAXBContext context = JAXBContext.newInstance(Catalog.class); 
     Marshaller marshaller = context.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     File catalogFile = new File(PATH_NAME); 
     marshaller.marshal(catalog, catalogFile); 

     } catch (JAXBException e) { 
     e.printStackTrace(); 
     } 
    } 
} 

@XmlRootElement 
class Catalog { 
    @XmlElement(name = "book") 
    private List<Book> bookList = new ArrayList<Book>(); 

    public List<Book> getBookList() { 
     return bookList; 
    } 

    public void addBook(Book book) { 
     bookList.add(book); 
    } 

    @Override 
    public String toString() { 
     return "Catalog [bookList=" + bookList + "]"; 
    } 


} 

@XmlRootElement 
@XmlType(propOrder = { "author", "title", "price", "date", "description"}) 
class Book { 
    private String id; 
    private String author; 
    private String title; 
    private double price; 
    private String date; 
    private String description; 

    public Book() { 
    } 

    public Book(String id, String author, String title, double price, 
     String date, String description) { 
     this.id = id; 
     this.author = author; 
     this.title = title; 
     this.price = price; 
     this.date = date; 
     this.description = description; 
    } 

    @XmlAttribute(name = "id") 
    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    public String getAuthor() { 
     return author; 
    } 

    public void setAuthor(String author) { 
     this.author = author; 
    } 

    public String getTitle() { 
     return title; 
    } 

    public void setTitle(String title) { 
     this.title = title; 
    } 

    public double getPrice() { 
     return price; 
    } 

    public void setPrice(double price) { 
     this.price = price; 
    } 

    public String getDate() { 
     return date; 
    } 

    public void setDate(String date) { 
     this.date = date; 
    } 

    public String getDescription() { 
     return description; 
    } 

    public void setDescription(String description) { 
     this.description = description; 
    } 

    @Override 
    public String toString() { 
     return "Book [id=" + id + ", author=" + author + ", title=" + title 
      + ", price=" + price + ", date=" + date + ", description=" 
      + description + "]"; 
    } 

} 
+0

Hmm, j'ai changé les résultats en String et j'ai retiré la distribution NodeList mais j'ai la même erreur. Je pense que l'erreur pourrait être en train de me dire que XPathQuery est la chaîne qui cause le problème, ce qui rendrait ce code impossible à corriger sans changer complètement la façon dont je vais m'y prendre ... –

+0

Oh okay malade juste mise à jour le code dans la question d'origine –

+0

Erreur complète: Exception dans le fil "principal" java.lang.ClassCastException: java.lang.String ne peut pas être converti en org.w3c.dom.Node Ligne: results = generatedPath.evaluate (xPathQuery) –

0

Si à partir de zéro, je suggère JDOM ou DOM4J comme des alternatives (regarder des tutoriels pour les deux) aux classes standard de bibliothèque Java (org.w3c.dom *.). Ils sont plus faciles à travailler. Jaxen travaillera avec les deux.