View Full Version : [JAVA] parsing file XML
AbuJaffa
17-05-2006, 17:24
ciao a tutti
Devo poter leggere da un file xml (feed rss) titoli, sorgenti e contenuti delle notizie. Ho utilizzato le librerie StAX per effettuare il parsing del file xml, però a me interessa estrapolare solo le parti dette sopra, cioè filtrare dal risultato del parsing solo alcune zone. Devo farlo in maniera grezza, cioè scandendo i risultati oppure c'è una via maestra più veloce? :)
Grazie a tutti...
Ci sono tanti modi, e tutti dipendono da quello che vuoi fare. Per esempio potresti utilizzare una trasformazione XSLT.
AbuJaffa
17-05-2006, 17:48
Allora, devo prelevare titolo, contenuto, link e data della notizia.
Cosa sarebbe questa trasformazione XSLT?
XSL (http://www.w3.org/Style/XSL/) è un linguaggio che ti permette di definire una trasformazione applicabile ad un documento XML per ottenere tipicamente un altro documento XML.
Puoi utilizzarlo come approccio completamente alternativo al tuo, o utilizzarlo solo nel punto in cui ti serve attraverso un'espressione XPath. Ma preferisco non dilungarmi su questo perchè forse *devi* utilizzare stax.
Se invece devi procedere con una fase di parsing e con una successiva fase di "filtro", allora puoi tentare comunque con XPath, prendendo spunto da quanto esposto qui (http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/xpath/package-summary.html#package_description) .
AbuJaffa
17-05-2006, 18:09
uhm... :confused: senti a questo punto per non fare dei controlli man mano che il processo di parsing va avanti il che porterebbe sicuramente a scivere codice lungo e inefficiente non sarebbe meglio utilizare DOM? Potresti farmi vedere un po di codice d'esempio sul suo utilizzo? Grazie... :)
Scusa ma StaX non lavora tipo DOM e quindi non puoi usare quello anche per l'estrazione??
altrimenti puoi vedere qui che c'è un jar apposito x gestire RSS in java..ma forse è troppo per quello che devi fare
https://rome.dev.java.net/
ciao
Potresti al limite anche usare castor.
E un oggetto che da un file schema ti genera degli oggetti che ti rappresento il file XML, e ti genera i metodi per fare il marshal e l'unmarshal.
Pero forse è un po troppo grossa e dispendiosa come soluzione, ti consiglio di usare XPATH
uhm... :confused: senti a questo punto per non fare dei controlli man mano che il processo di parsing va avanti il che porterebbe sicuramente a scivere codice lungo e inefficiente non sarebbe meglio utilizare DOM? Potresti farmi vedere un po di codice d'esempio sul suo utilizzo? Grazie... :)
Ribadisco che, prendendo spunto da qui (http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/xpath/package-summary.html#package_description), e te lo riporto per comodità:
XPath xpath = XPathFactory.newInstance().newXPath();
String expression = "/widgets/widget";
InputSource inputSource = new InputSource("widgets.xml");
NodeSet nodes = (NodeSet) xpath.evaluate(expression, inputSource, XPathConstants.NODESET);
puoi fare una cosa del genere:
// assumo che in qualche modo ho effettuato il parsing dell'xml
// e ho costruito un albero DOM
Document xmlDom = ...;
// Definisco l'espressione XPath come più mi conviene
String expression = ...;
XPath xpath = XPathFactory.newInstance().newXPath();
// Ottiengo una "vista" sui nodi filtrati e ci faccio quello che voglio
NodeSet nodes = (NodeSet) xpath.evaluate(
expression,
new DOMSource(xmlDom),
XPathConstants.NODESET);
ciao a tutti
Devo poter leggere da un file xml (feed rss) titoli, sorgenti e contenuti delle notizie. Ho utilizzato le librerie StAX per effettuare il parsing del file xml, però a me interessa estrapolare solo le parti dette sopra, cioè filtrare dal risultato del parsing solo alcune zone. Devo farlo in maniera grezza, cioè scandendo i risultati oppure c'è una via maestra più veloce? :)
Grazie a tutti...
usa XPath
texerasmo
18-05-2006, 12:39
comunque una trasformazione xml xsl è sempre più semplice ti fai restiuire quello che vuoi.
fai il poli? :confused:
io facevo :D
AbuJaffa
19-05-2006, 17:33
fai il poli? :confused:
si!
ah ecco è il progetto di Ing Sw :asd:
ti posto quello che ho scritto io :D
public class NewsManager {
protected ArrayList<NewsItem> RSSList;
protected URL RSSURL;
public NewsManager(String U) throws MalformedURLException {
RSSList = new ArrayList<NewsItem>();
RSSURL = new URL(U);
}
public NewsManager() throws MalformedURLException {
RSSList = new ArrayList<NewsItem>();
//RSSURL = new URL("http://www.repubblica.it/rss/homepage/rss2.0.xml");
RSSURL = new URL("http://www.elet.polimi.it/upload/lazaric/ingsw/rss2.0example.xml");
}
public void changeRSSURL(String U) throws MalformedURLException {
RSSURL=new URL(U);
}
public void retrieveNews() throws IOException, XMLStreamException {
//FileInputStream in = new FileInputStream("C:/Documents and Settings/Pitonti/Documenti/Programmazione/RSS-Example.xml");
//InputStream in = RSSURL.openStream();
FileInputStream in = new FileInputStream("D:/rss2.0example.xml");
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader parser = factory.createXMLStreamReader(in);
while (true) {
String localName=new String();
NewsItem news = new NewsItem();
int event = parser.next();
if (event == XMLStreamConstants.END_DOCUMENT) {
parser.close();
break;
}
if (event == XMLStreamConstants.START_ELEMENT && parser.getLocalName().equals("item")) {
do {
event=parser.next();
if (event == XMLStreamConstants.START_ELEMENT) {
localName=parser.getLocalName();
if (localName.equals("title")) {
parser.next();
news.setNewsTitle(parser.getText());
}
if (localName.equals("description")) {
parser.next();
news.setNewsText(parser.getText());
}
if (localName.equals("link")) {
parser.next();
news.setNewsLink(parser.getText());
}
if (localName.equals("author")) {
parser.next();
news.setSourceDesc(parser.getText());
}
if (localName.equals("category")) {
for (int i = 0; i < parser.getAttributeCount(); i++)
if (parser.getAttributeLocalName(i).equals("domain"))
news.setSourceLink(parser.getAttributeValue(i));
}
}
if (event == XMLStreamConstants.END_ELEMENT)
if(parser.getLocalName().equals("item")) break;
} while (true);
RSSList.add(news);
}
}
}
public void addCommentToNews(String cnt, String us, int nws) throws UnknownNewsException{
try{RSSList.get(nws).addComment(new Comment(cnt,us));}
catch (Exception e) {throw new UnknownNewsException();}
}
public void printRSS() {
System.out.println("Notizie prese dal feed RSS di " + RSSURL);
for (NewsItem n:RSSList) n.printNews();
}
public String getRSSString() {
String output = "Notizie prese dal feed RSS di " + RSSURL;
for (NewsItem n:RSSList) output=output+n.getNewsString();
return output;
}
public ArrayList<NewsItem> getRSSArray() {
return RSSList;
}
public static void main(String[] args) throws IOException, XMLStreamException {
NewsManager NM = new NewsManager();
NM.printRSS();
NM.retrieveNews();
NM.printRSS();
}
}
ho anche creato
public class RSSServer {
NewsManager NM;
UserManager UM;
public RSSServer() throws MalformedURLException {
NM = new NewsManager();
UM = new UserManager();
insieme alla dichiarazione del socket e degli utenti, visto che non so come gestire i db :stordita:
AbuJaffa
20-05-2006, 14:16
scusa... ma la gestione degli utenti come andrà implementata? Maneggiando db?
no non avremo la possibilità di gestire i db ma salveremo gli utenti con le relative informazioni su dei file di txt che ancora non abbimo affrontato :stordita:
ora sto alla grafica ed è una palla pazzesca :muro:
AbuJaffa
20-05-2006, 14:51
altra cosa... come hai implementato il protocollo di comunicazione fra client e server?
altra cosa... come hai implementato il protocollo di comunicazione fra client e server?
io faccio partire il server che scarica le notizie e gestisce i commenti e il client scarica dal server le notizie che gli interessano e tutti i commenti alla notizia questo è il codice di gestione client-server
public class RSSServerThread extends Thread {
private Socket socket = null;
private RSSServer mainHost;
private long ThrID;
public RSSServerThread(Socket socket,RSSServer rss) {
super("RSSServerThread");
this.socket = socket;
mainHost=rss;
ThrID=this.getId();
}
public void run() {
try {
Message inputMessage = null; //Messaggi in arrivo da client
String utente;
boolean connected=true;
boolean uslog;
OutputStream o = socket.getOutputStream();
InputStream i = socket.getInputStream();
ObjectOutputStream outS = new ObjectOutputStream(o);
ObjectInput inS = new ObjectInputStream(i);
//Inizializzati gli stream di ingresso e uscita
System.out.println("Thread "+ThrID+" in esecuzione!");
do { //Ciclo esterno x determinare la modalità di funzionamento
//Ricezione Id che indica il modo di funzionamento
System.out.println(ThrID+": Attendo l'azione da eseguire...");
inputMessage = (Message) inS.readObject();
if (inputMessage.getClass()!=RequestMessage.class) {
outS.writeObject(new ErrorMessage(new UnexpectedMessageException(),1));
outS.flush();
outS.close();
inS.close();
socket.close();
return;
}//Attende un messaggio di richiesta
switch( ((RequestMessage) inputMessage).getContent() ) {
case 0: //Il client vuole disconnettersi
outS.writeObject(new Message("Richiesta accolta, thread in chiusura"));
System.out.println(ThrID+": Ho ricevuto una richiesta di disconnessione...Chiusura in corso");
connected=false;
break;
case 1: //Un utente si vuole loggare e utilizzare i suoi privilegi
outS.writeObject(new Message("Richiesta accolta, attesa di Username e Password"));
System.out.println(ThrID+": Ho ricevuto una richiesta di login, attendo dati utente...");
inputMessage = (Message) inS.readObject(); //Ricezione utente e pwd
if (inputMessage.getClass()!=LoginMessage.class) {
outS.writeObject(new ErrorMessage(new UnexpectedMessageException(),1));
outS.flush();
outS.close();
inS.close();
socket.close();
return;
}//Se il messaggio non è di login, riscontra l'errore e si disconnette
System.out.println(ThrID + ": l'utente "+((LoginMessage) inputMessage).getUser()+" sta provando a connettersi");
uslog=true;
try {mainHost.UM.userLogin(
((LoginMessage) inputMessage).getUser(),
((LoginMessage) inputMessage).getPassword());}
//Tentativo di login
catch (UnknownUserException e) {
System.out.println(ThrID+": l'utente è sconosciuto!");
outS.writeObject(new ErrorMessage(e,10));
outS.flush();
uslog=false;
}//Errore! Utente sconosciuto, riscontra l'errore e torna in attesa
catch (IncorrectLoginException e) {
System.out.println(ThrID+": "+e.getMessage());
outS.writeObject(new ErrorMessage(e,11));
outS.flush();
uslog=false;
}//Errore! Login non effettuato, riscontra l'errore e torna in attesa
utente=((LoginMessage) inputMessage).getUser();
if (uslog) {
System.out.println(utente + " loggato con successo!");
outS.writeObject(new ResponseMessage(1)); //Messaggio di login avvenuto
outS.flush();
}
while (uslog) {
System.out.println(utente + " --> Attesa di un nuovo comando...");
inputMessage = (Message)inS.readObject(); //Ciclo di attesa dei messaggi di richiesta
if (inputMessage.getClass()!=RequestMessage.class) {
outS.writeObject(new ErrorMessage(new UnexpectedMessageException(),1));
outS.flush();
outS.close();
inS.close();
socket.close();
return;
}//Se il messaggio non è di comando, riscontra l'errore e si disconnette
else {
outS.writeObject(new ResponseMessage(1)); //Messaggio di richiesta accolta
outS.flush();
switch ( ((RequestMessage)inputMessage).getContent() ){
case 0: //Richiesto il logout
System.out.println(utente + " --> Richiesto il logout");
uslog=false;
try {mainHost.UM.userLogout(utente);}
catch (Exception e){System.out.println(e);}
System.out.println(utente + " --> Logout effettuato");
break;
case 1: //Richiesta l'intera sequenza delle news
System.out.println(utente + " --> Richiesto l'invio delle news");
outS.reset();
outS.writeObject(mainHost.NM.getRSSArray());
outS.flush();
System.out.println(utente + " --> News inviate");
break;
case 2: //Richiesta di inserimento di un commento
System.out.println(utente + " --> Richiesto l'inserimento di un commento");
outS.writeObject(new ResponseMessage(1));
outS.flush();
inputMessage = (RequestMessage)inS.readObject(); //Attesa del messaggio di commento
int newsToComm = ((RequestMessage)inputMessage).getContent();
String Comm=((RequestMessage)inputMessage).getInformations();
System.out.println(utente + " invia il commento "+Comm+" per la notizia "+newsToComm);
try {
mainHost.NM.addCommentToNews(Comm,utente,newsToComm);
outS.writeObject(new ResponseMessage(1));
outS.flush();
System.out.println(utente + " --> Commento aggiunto");
}
catch(UnknownNewsException e) {
outS.writeObject(new ErrorMessage(e,12));
outS.flush();
System.out.println(utente + " --> Commento non aggiunto: notizia inesistente");
}
break;
}
}
};
break;
case 2: //Il client vuole creare una nuova utenza
outS.writeObject(new Message("Richiesta accolta, attesa dei dati completi"));
System.out.println(ThrID+": Ho ricevuto una richiesta di registrazione, attendo dati utente...");
break;
case 3: //Il client vuole eliminare un'utenza esistente
outS.writeObject(new Message("Richiesta accolta, attesa di Username e Password"));
System.out.println(ThrID+": Ho ricevuto una richiesta di eliminazione, attendo dati utente...");
break;
case 4: //Il client vuole una conferma dell'attività del server
System.out.println(ThrID+": Ho ricevuto una richiesta di ping, confermo attività");
outS.writeObject(new Message("Server attivo!"));
break;
default: //Valore non standard
outS.writeObject(new ErrorMessage(new UnexpectedMessageException(),1));
connected=false;
break;
}
} while(connected);
System.out.println(ThrID + ": Chiusura del thread");
outS.close();
inS.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Fenomeno85
21-05-2006, 12:31
il poli domina :asd:
abu in che scaglione sei?
Io sto in questo momento gestendo il server e devo dire che è un bel puttanaio :D ma divertente.
~§~ Sempre E Solo Lei ~§~
AbuJaffa
21-05-2006, 13:46
LF a PO con San Pietro.
Mi aspettavo qualcosa di più visti i progetti degli anni scorsi ma, devo dire che tutto sommato è carino anche questo. :D
AbuJaffa
21-05-2006, 14:03
http://img91.imageshack.us/my.php?image=msg2ml.gif
Scusate ma nella slide dei messaggi strutturati come mai sono presenti due classi entrambe di nome CommandMsg? Quella che eredita da message dovrebbe chiamarsi requestMsg. Infatti una richiesta può essere un comando o una risposta.
Fenomeno85
21-05-2006, 14:05
siamo nello stesso scaglione :asd:
~§~ Sempre E Solo Lei ~§~
Fenomeno85
21-05-2006, 14:09
http://img91.imageshack.us/my.php?image=msg2ml.gif
Scusate ma nella slide dei messaggi strutturati come mai sono presenti due classi entrambe di nome CommandMsg? Quella che eredita da message dovrebbe chiamarsi requestMsg. Infatti una richiesta può essere un comando o una risposta.
io quella slide l'ho bellamente scartata e mi son fatto un insieme di classi per la gestione :D
~§~ Sempre E Solo Lei ~§~
lameroni :O
che è quella slide?
Fenomeno85
21-05-2006, 14:16
lameroni :O
che è quella slide?
www.elet.polimi.it/upload/mplebani :D
comunque pito ma te fai protocolli?! :D
~§~ Sempre E Solo Lei ~§~
si purtroppo e ho già visto troppi lameroni da ammazzare :muro:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.