PDA

View Full Version : [JAVA] Serve la ricorsione???


xxdavide84xx
15-01-2008, 09:52
Ci vuole la ricorsione??? Io ho queste 2 funzioni createBodyObjects() e createRObjects().

Io vorrei che mi memorizzasse in body prima 1 volta i valori di createBodyObjects() e poi entrasse in createRObjects() fino a che w:r non è uguale a null e mi memorizzasse i valori.

Poi dovrebbe ripassare a createBodyObjects() e incrementare i e memorizzare i valori, e poi rientrare nella seconda fino a che w:r non è uguale a null....

Dovrebbe fare questo fino a che i < bodyNodes.size(); (bodyNodes.size();=869 nel mio caso...)

Serve la ricorsione???
Qualcuno può aiutarmi a mettere in JAVA quello che ho detto?

Perchè ora come ora fa così entra in createBodyObjects() prende i valori, va in createRObjects() solo 1 volta prende il primo valore di w:r e torna createBodyObjects() e fai il giro prendendo sempre e solo il primo valore di w:r...

codice: private void createBodyObjects() {
for ( int i = 0; i < bodyNodes.size(); i++) {
Node bodyNode = (Node)bodyNodes.elementAt(i);
Body body = new Body();
Node paragraphNode = getChildNode(bodyNode, "w:pPr");
if ( paragraphNode != null ) {
Node stileNode = getChildNode(paragraphNode, "w:pStyle");
if ( stileNode != null )
body.stile = getAttributeValue(stileNode, "w:val");
Node jcNode = getChildNode(paragraphNode, "w:jc");
if ( jcNode != null )
body.jc = getAttributeValue(jcNode, "w:val");
}
createRObjects(body, bodyNode);
bodyObjects.addElement(body);
}
}

private void createRObjects(Body body, Node bodyNode) {
Node rNode = getChildNode(bodyNode, "w:r");
if ( rNode != null ) {
Node rPrNode = getChildNode(rNode, "w:rPr");
if ( rPrNode != null ) {
Node grassettoNode = getChildNode(rPrNode, "w:b");
if ( grassettoNode != null )
body.grassetto = getAttributeValue(grassettoNode, "w:val");
Node italicoNode = getChildNode(rPrNode, "w:i");
if ( italicoNode != null )
body.italico = getAttributeValue(italicoNode, "w:val");
}
Node testoNode = getChildNode(rNode, "w:t");
if ( testoNode != null ) {
Node testoNode1 = getChildNode(testoNode, "#text");
if ( testoNode1 != null )
body.testo = testoNode1.getNodeValue();
}

}

}

banryu79
15-01-2008, 11:01
Così a naso (non conosco l'ambito di programmazione) direi che qui forse va ciclata tutta l'estrazione per ogni Node "w:r" contenuto nel Node passato come parametro "bodyNode" al metodo getChildNode(), se non ho capito male?

1) Non c'è un metodo per conoscere in quel Node (bodyNode) quanti nodi "child" di tipo "w:r" sono contenuti?

2) Non è che il metodo getChildNode() ti torna il primo Node child del tipo specificato (w:r) che incontra?

Nel caso 1) basterebbe invocare quel metodo per ottenere quanti Node child del tipo che ti interessa ci sono e fare un ciclo for...

Nel caso 2) invece getChildNode() funzia come un iteratore e magari basta utilizzare un while, ad esempio:

while( getChildNode(bodyNode, "w:r") != null) {
//
}

oppure esiste un metodo del tipo getNextNode()?


Comunque l'eventuale ciclo lo inserirei appena dentro il corpo del metodo:

private void createRObjects(Body body, Node bodyNode) {


Node rNode = getChildNode(bodyNode, "w:r");


if ( rNode != null ) {
Node rPrNode = getChildNode(rNode, "w:rPr");
if ( rPrNode != null ) {
Node grassettoNode = getChildNode(rPrNode, "w:b");
if ( grassettoNode != null )
body.grassetto = getAttributeValue(grassettoNode, "w:val");
Node italicoNode = getChildNode(rPrNode, "w:i");
if ( italicoNode != null )
body.italico = getAttributeValue(italicoNode, "w:val");
}
Node testoNode = getChildNode(rNode, "w:t");
if ( testoNode != null ) {
Node testoNode1 = getChildNode(testoNode, "#text");
if ( testoNode1 != null )
body.testo = testoNode1.getNodeValue();
}

}

}


Ciao :)

xxdavide84xx
15-01-2008, 11:33
1) Quello che mi chiedevo anch'io... qui
http://www.hwupgrade.it/forum/showthread.php?t=1652563
dove ho messo il programma completo (anche se qualche modifica l'ho effettuata...)

2) while( getChildNode(bodyNode, "w:r") != null)
sarebbe come dire
while ( rNode !=null)
visto che Node rNode = getChildNode(bodyNode, "w:r");
e se faccio così mi va in crash il programma.....

Grazie comunque!

banryu79
15-01-2008, 11:39
1) Quello che mi chiedevo anch'io...

2) while( getChildNode(bodyNode, "w:r") != null)
sarebbe come dire
while ( rNode !=null)
visto che Node rNode = getChildNode(bodyNode, "w:r");
e se faccio così mi va in crash il programma.....

Grazie comunque!

1) Ma questi metodi fanno parte di classi di qualche libreria/package?

2) no, la mia ipotesi era che getChildNode() funzionasse un po' come un iteratore dentro il nodo... ma non credo sia così in effetti, visto come viene usata non può essere :)

xxdavide84xx
15-01-2008, 11:43
Questa:
private Node getChildNode(Node node, String nodeName) {
NodeList childNodes = node.getChildNodes();
for ( int i = 0; i < childNodes.getLength(); i++) {
Node childNode = childNodes.item(i);
if ( childNode.getNodeName().equals(nodeName) )
return childNode;
}
return null;
}


Questo è il mio programma completo:
import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;

public class aa {
Vector styleNodes = new Vector();

Vector styleObjects = new Vector();

Vector rNodes = new Vector();

Vector bodyNodes = new Vector();

Vector bodyObjects = new Vector();

public aa() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();
}
catch (ParserConfigurationException e) {
e.printStackTrace();
System.exit(1);
}
Document document = null;
try {
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("Martedì 15.txt", false)));
document = builder.parse(new File("C:\\Documents and settings\\Administrator\\Desktop\\DAVIDE\\Dom\\tesi.xml"));
findStyleNodes(document);
createStyleObjects();
printStyles(pw);
findBodyNodes(document);
createBodyObjects();
printBody(pw);
pw.close();
}
catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}

private void findStyleNodes(Node startingNode) {
NodeList childNodes = startingNode.getChildNodes();
for ( int i = 0; i < childNodes.getLength(); i++) {
Node actualNode = childNodes.item(i);
if ( isStyleNode(actualNode) )
styleNodes.addElement(actualNode);
if ( actualNode.hasChildNodes() )
findStyleNodes(actualNode);
}
}

private boolean isStyleNode(Node node) {
return node.getNodeName().equals("w:style");
}

private void createStyleObjects() {
for ( int i = 0; i < styleNodes.size(); i++) {
Node styleNode = (Node)styleNodes.elementAt(i);
Style style = new Style();
Node uinameNode = getChildNode(styleNode, "wx:uiName");
if ( uinameNode != null )
style.name = getAttributeValue(uinameNode, "wx:val");
if ( uinameNode == null ) {
Node nameNode = getChildNode(styleNode, "w:name");
if ( nameNode != null )
style.name = getAttributeValue(nameNode, "w:val");
}
Node basedNode = getChildNode(styleNode, "w:basedOn");
if ( basedNode != null )
style.based = getAttributeValue(basedNode, "w:val");
Node pPrNode = getChildNode(styleNode, "w:pPr");
if ( pPrNode != null ) {
Node pstileNode = getChildNode(pPrNode, "w:pStyle");
if ( pstileNode != null )
style.pstile = getAttributeValue(pstileNode, "w:val");
Node jcNode = getChildNode(pPrNode, "w:jc");
if ( jcNode != null )
style.jc = getAttributeValue(jcNode, "w:val");
}
Node paragraphNode = getChildNode(styleNode, "w:rPr");
if ( paragraphNode != null ) {
Node fontNode = getChildNode(paragraphNode, "wx:font");
if ( fontNode != null )
style.font = getAttributeValue(fontNode, "wx:val");
Node sizeNode = getChildNode(paragraphNode, "w:sz");
if ( sizeNode != null )
style.size = getAttributeValue(sizeNode, "w:val");
Node grassettoNode = getChildNode(paragraphNode, "w:b");
if ( grassettoNode != null )
style.grassetto = getAttributeValue(grassettoNode, "w:val");
Node italicoNode = getChildNode(paragraphNode, "w:i");
if ( italicoNode != null )
style.italico = getAttributeValue(italicoNode, "w:val");
Node sottolineatoNode = getChildNode(paragraphNode, "w:u");
if ( sottolineatoNode != null )
style.sottolineato = getAttributeValue(sottolineatoNode, "w:val");
}
styleObjects.addElement(style);
}
}

private String getAttributeValue(Node node, String attributeName) {
NamedNodeMap attributes = node.getAttributes();
if ( attributes == null )
return "";
Node item = attributes.getNamedItem(attributeName);
if ( item == null )
return "";
return item.getNodeValue();
}

private Node getChildNode(Node node, String nodeName) {
NodeList childNodes = node.getChildNodes();
for ( int i = 0; i < childNodes.getLength(); i++) {
Node childNode = childNodes.item(i);
if ( childNode.getNodeName().equals(nodeName) )
return childNode;
}
return null;
}

private void printStyles(PrintWriter pw) {
for ( int i = 0; i < styleObjects.size(); i++) {
Style style = (Style)styleObjects.elementAt(i);
System.out.println(style);
pw.println(style);
}
}

public static void main(String args[]) {
new aa();
}

class Style {
String name;

String based;

String pstile;

String jc;

String font;

String size;

String grassetto;

String italico;

String sottolineato;

public String toString() {
StringBuffer buffer = new StringBuffer();
if ( name != null ) {
buffer.append("Stile: " + name + "\n");
if ( based != null )
buffer.append(" Basato su: " + based + "\n");
if ( pstile != null )
buffer.append(" pStyle: " + pstile + "\n");
if ( jc != null )
buffer.append(" Jc: " + jc + "\n");
if ( font != null )
buffer.append(" Font: " + font + "\n");
if ( size != null )
buffer.append(" Dimensione: " + size + "\n");
if ( grassetto != null )
buffer.append(" Grassetto " + grassetto + "\n");
if ( italico != null )
buffer.append(" Italico " + italico + "\n");
if ( sottolineato != null )
buffer.append(" Sottolineato: " + sottolineato + "\n");
}
return buffer.toString();
}
}

private void findBodyNodes(Node startingNode) {
NodeList childNodes = startingNode.getChildNodes();
for ( int i = 0; i < childNodes.getLength(); i++) {
Node actualNode = childNodes.item(i);
if ( isBodyNode(actualNode) )
bodyNodes.addElement(actualNode);
if ( actualNode.hasChildNodes() )
findBodyNodes(actualNode);
}
}

private boolean isBodyNode(Node node) {
return node.getNodeName().equals("w:p");
}

private void createBodyObjects() {
for ( int i = 0; i < bodyNodes.size(); i++) {
Node bodyNode = (Node)bodyNodes.elementAt(i);
Body body = new Body();
Node paragraphNode = getChildNode(bodyNode, "w:pPr");
if ( paragraphNode != null ) {
Node stileNode = getChildNode(paragraphNode, "w:pStyle");
if ( stileNode != null )
body.stile = getAttributeValue(stileNode, "w:val");
Node jcNode = getChildNode(paragraphNode, "w:jc");
if ( jcNode != null )
body.jc = getAttributeValue(jcNode, "w:val");
}
createRObjects(body, bodyNode);
bodyObjects.addElement(body);
}
}

private void createRObjects(Body body, Node bodyNode) {
Node rNode = getChildNode(bodyNode, "w:r");
if ( rNode != null ) {
Node rPrNode = getChildNode(rNode, "w:rPr");
if ( rPrNode != null ) {
Node grassettoNode = getChildNode(rPrNode, "w:b");
if ( grassettoNode != null )
body.grassetto = getAttributeValue(grassettoNode, "w:val");
Node italicoNode = getChildNode(rPrNode, "w:i");
if ( italicoNode != null )
body.italico = getAttributeValue(italicoNode, "w:val");
}
Node testoNode = getChildNode(rNode, "w:t");
if ( testoNode != null ) {
Node testoNode1 = getChildNode(testoNode, "#text");
if ( testoNode1 != null )
body.testo = testoNode1.getNodeValue();
}
}
}

private void printBody(PrintWriter pw) {
for ( int i = 0; i < bodyObjects.size(); i++) {
Body body = (Body)bodyObjects.elementAt(i);
System.out.println(body);
pw.println(body);
}
}

class Body {
String stile;

String jc;

String grassetto;

String italico;

String testo;

public String toString() {
StringBuffer buffer = new StringBuffer();
if ( stile != null )
buffer.append("Stile body: " + stile + "\n");
if ( jc != null )
if ( grassetto != null )
buffer.append(" Grassetto body " + grassetto + "\n");
if ( italico != null )
buffer.append(" Italico body " + italico + "\n");
buffer.append(" Testo body: " + testo + "\n");
return buffer.toString();
}
}
}

banryu79
15-01-2008, 12:51
private Node getChildNode(Node node, String nodeName) {
NodeList childNodes = node.getChildNodes();
for ( int i = 0; i < childNodes.getLength(); i++) {
Node childNode = childNodes.item(i);
if ( childNode.getNodeName().equals(nodeName) )
return childNode;
}
return null;
}

Perfetto... come vedi in getChildNode() il chiamante passa un oggetto Node al cui interno cercare un Nodo "figlio" il cui nome corrisponda a quello cercato, cioè il parametro "nodeName".

Il Nodo passato come parametro potrebbe contenere zero o più Nodi "figli"...
la lista di tutti i "nodi figli" contenuti in un dato nodo viene ottenuta così:


NodeList childNodes = node.getChildNodes();


Ora in "childNodes" c'è la lista di tutti i nodi figlio di "node".

Però il resto del metodo si limita a prendere un "nodo figlio" dalla lista, controllare se il suo nome è uguale a quello voluto ("nodeName"), quindi tornare quel Nodo in caso affermativo, altrimenti proseguire l'iterazione prendendo il prossimo "nodo figlio" e così via, finchè non l'ha trovato o non ha raggiunto la fine della lista.

Chiaro che appena trova il primo che corrisponde, il metodo torna subito.


Quindi nel tuo codice, non devi utilizzare getChildNode() ma devi utilizzare un metodo che ti personalizzi tu, e che, passato in ingresso un Nodo e una String ti trovi, nel nodo padre tutti i nodi figlio con quel nome.


public NodeList getAllChildNodes(Node parentNode, String childsName) {
// trova tutti i nodi figlio che hanno il nome == childsName
}

Nota: se sai come istanziare una NodeList vuota e la sua interfaccia pubblica ti permette di popolarla puoi usare quella come tipo di ritorno del metodo.


@EDIT:
Ah, prima però sarebbe bene se tu guardassi la classe Node per vedere se già c'è un metodo che fa questo lavoro...

xxdavide84xx
15-01-2008, 13:38
Se mettessi al posto di if while non potrei risolvere????
Così:

private Node getAllChildNode(Node node, String nodeName) {
NodeList childNodes = node.getChildNodes();
for ( int i = 0; i < childNodes.getLength(); i++) {
Node childNode = childNodes.item(i);
while ( childNode.getNodeName().equals(nodeName) )
return childNode;
}
return null;
}

Forse qui a pagina 480 e 481 parlano di queste cose....ma non riesco a trovare bene come fare....mi puoi dare una mano a buttare giù il codice?
http://books.google.com/books?id=p8980V437wUC&pg=PA480&lpg=PA480&dq=java+tutti+i+metodi+coi+nodi&source=web&ots=6dI7ZLIUEa&sig=ZYsFgzxQoIjNjm_J2U3Fi7J4YZU#PPA480,M1

banryu79
15-01-2008, 14:20
Scusa ma adesso fino a stasera sono in sessione di programmazione con altri colleghi e non ho tempo; domattina :D

P.S.: quel while non credo vada bene... xchè continua ad aggiungere nodi solo finché ogni nodo incontrato ha il nome che vuoi... invece credo tu li voglia attraversare tutti e ogni volta controlli se quello attraversato ha il nome che cerchi.

A meno che quelli con lo stesso nome stiano tutti "vicini" (cioè sono contigui nella lista), in quel caso il while va bene, ma la struttura dati sai te come è fatta.

xxdavide84xx
15-01-2008, 14:36
Appena puoi prova a postare....GRAZIE!!!

Anche col while mi da lo stesso risultato..ossia mi stampa tutti i w:p con w:pPr e i suoi attributi e col primo w:r


w:p è così composto:
http://img266.imageshack.us/img266/1116/catenawrjy2.png
come vedi dentro a w:p c'è sempre 1 solo w:pPr e possono essere 0 o più w:r.... mentre aml:annotation non mi interessano...

Quindi il problema è anche memorizzarli bene poi...oltre che trovarli tutti!!!
Cmq in quel libro ci sono i metodi del node, e dice che
NodeList getChildNodes
restituisce una NodeList contenente tutti i figli del Node corrente....
Aspetto tue notizie appena puoi e GRAZIE ancora...

Intanto naturalmente io provo a vedere se riesco da solo...

banryu79
15-01-2008, 15:29
A proposito, mi è venuto un dubbio: tu ce l'hai sottomano la documentazione (javadoc) relativa?

Guarda qua che ce la fai da solo ;)

-> Interface Node (http://xerces.apache.org/xerces2-j/javadocs/api/org/w3c/dom/Node.html)

-> Interface NodeList (http://xerces.apache.org/xerces2-j/javadocs/api/org/w3c/dom/NodeList.html)

xxdavide84xx
16-01-2008, 00:57
Invece avrei bisogno di una MANO, perchè con le prove che ho fatto ho solo che peggiorato la situazione....

E non sono venuto a capo di nulla....

private Node getChildNode(Node node, String nodeName) {
NodeList childNodes = node.getChildNodes();
for ( int i = 0; i < childNodes.getLength(); i++) {
Node childNode = childNodes.item(i);
if ( childNode.getNodeName().equals(nodeName) )
return childNode;
}
return null;
}

ma childNode è già una NodeList....

Mi sono perso.....

Secondo te cosa dovrei cambiare o aggiungere?

Mi ero dimenticato:
Se io creo una classe P e una classe R separate riesco a stampare tutti i w:r....
solo che prima mi stampa tutti i w:p e poi tutti i w:r....
Quindi in teoria ho i metodi giusti, è solo la concatenzaione che non funziona BENE....

A me andrebbe benissimo che w:p rimanesse sempre con gli stessi valori per tutti nodi w:r.....
es:
Stile body: CorpoTesi
jc: centrato
Testo body: ciao
grassetto: off
poi se cambia w:r, ma siamo nello stesso nodo potrebbe tenere in memoria in w:p che rimangono uguali
Stile body: CorpoTesi
jc: centrato
Testo: Gino
grassetto on

Oppure andrebbe bene mi scrive i w:p solo 1 volta e poi di fila tutti i w:r appartenenti allo stesso w:p come qui sotto:
Stile body: CorpoTesi
jc: centrato
Testo body: ciao
grassetto: off
Testo: Gino
grassetto on

A me andrebbero bene entrambi i modi, ma non riesco a implementare il programma per fare ciò....SPERO proprio tu riesca ad aiutarmi....

xxdavide84xx
16-01-2008, 11:23
Mi è stato dato questo suggerimento:

"Dipende cosa vuoi far ritornare dal metodo! Node ovviamente no, visto che rappresenta solo 1 nodo. Potresti far ritornare un List<Node> (nel metodo crei ad esempio un ArrayList e ci appendi tutti i nodi che devi far ritornare).

Ma potresti anche far ritornare un NodeList. Nota che NodeList non è una classe ma una interfaccia. Quindi devi far ritornare una implementazione "concreta" di questa interfaccia. Quale implementazione? Semplice, la definisci tu! NodeList è molto semplice, ha solo 2 metodi: getLength() e item() e questi dati (lunghezza e elemento i-esimo) li hai anche da un ArrayList."

Per te qual'è la più semplice soluzione?

banryu79
16-01-2008, 16:18
Ciao, oggi sono stato fuori sede tutto il giorno da un cliente.
Che ne dici di una cosa così:

private ArrayList<Node> getChildNode(Node node, String nodeName) {

ArrayList<Node> nodeList = new ArrayList<Node>();

NodeList childNodes = node.getChildNodes();
for ( int i = 0; i < childNodes.getLength(); i++) {
Node childNode = childNodes.item(i);
if ( childNode.getNodeName().equals(nodeName) )
nodeList.add(childNode);
}
return null;
}


Alla fine il metodo ti restituisce un ArrayList di oggetti Node.