webForumDet fria alternativet

Annan lösning på rekursion vid läsande av "XML"-dokument

2 svar · 697 visningar · startad av erka

erkaMedlem sedan dec. 19996 522 inlägg
#1

Hej
Sitter med en labbuppgift där vi ska läsa in en xhtml fil, bearbeta den med hjälp av DOM, vi har en redan färdigklass till vårt förfogande. Vi ska läsa in informationen i filen och visa den i ett terminalfönster, en terminalbaserad webbläsare helt enkelt. Vi ska tex ersätta <b> taggar med något som kan visas som fettext i ett terminalfönster, dessa funktioner för att visa det finns i en klass som vi har fått. Jag har lyckats lösa det så det fungerar helt utmärkt men tänker nu om det finns fler sätt att lösa det på, ibland ser man inte skogen för alla träden. Man blir lätt låst. Problemen är hur man ska lösa nästlade taggar på ett sätt som jag inte har gjort, om det går, men det antar jag :D

Här är en del av funktionen som tar emot en xmlnode och stegar igenom alla dess noder

private boolean  inBody= false;
private int numberOfB = 0;
private int numberOfEm = 0;

public void printNodeLeaves(Node N)
{
	switch (N.getNodeType())
{
case Node.DOCUMENT_NODE:
case Node.ELEMENT_NODE:
String nName = N.getNodeName(); //Får ut taggar som B,P,EM osv
	
if (nName.equalsIgnoreCase("body")) inBody= true;
	 
if (nName.equalsIgnoreCase("b")){
  numberOfB++;
  System.out.print("<BOLD>");
}
if (nName.equalsIgnoreCase("p")) itw.newline(2);
if (nName.equalsIgnoreCase("em")){
	numberOfEm++;		 
	System.out.print("<KURSIV>");				
}

	  
//Rekursivfunktion	  
NodeList children= N.getChildNodes();
if (children != null)
    for (int i=0; i<children.getLength(); ++i){	    	
    	printNodeLeaves(children.item(i));	    	
}
	  
if (nName.equalsIgnoreCase("b")){
	numberOfB--;
	if(numberOfB==0) System.out.print("</AV>");
	if(numberOfEm>0) System.out.print("<KURSIV>");
}
  
if (nName.equalsIgnoreCase("em")) {
	numberOfEm--;
	if(numberOfEm==0) System.out.print("</AV>");
	if(numberOfB>0) System.out.print("<BOLD>");
}
	
if (nName.equalsIgnoreCase("p")) itw.newline(2);
	break;
	case Node.TEXT_NODE:
	if (inBody){ 	 		   
	    itw.print(N.getNodeValue().replaceAll("\n", " "));	    		  
	}
}

Ni ser ju konceptet, att varje sorts tagg jag ska representera med något annat får en räknare, den anropar dess barn rekursivt, sedan minskar den huvudnodens räknare så att man hela tiden kan hålla koll på nestlade taggar. Med nestlade menar jag att taggarna kan komma så här

<em><b>Hej</b>Tjenare<b></em>Fett</b>NormalTe<b>xt <b>Eller </b></b>

nackdelen är ju att ju fler taggar man vill kunna hantera blir det extremt mycket mer kod i varje koll vid if (nName.equalsIgnoreCase("em")), men jag ser verkligen inget annat sätt att lösa det på.

spangoMedlem sedan juni 20008 205 inlägg
#2

Borde det inte enklare att göra nåt sånt här:

if (nName.equalsIgnoreCase("b")){
	System.out.print("<BOLD>");
	NodeList children= N.getChildNodes();
	if (children != null)
		for (int i=0; i<children.getLength(); ++i){	    	
		    	printNodeLeaves(children.item(i));	    	
		}
	System.out.print("</BOLD>");
}

D.v.s., skriv ut det som ska skrivas vid början av en tagg, skriv ut alla undernoder rekursivt, skriv ut det som visar att det är slut på taggen. (Går att banta koden genom att skriva om hela metoden, men det överlåter jag till dig :) )

LimeMedlem sedan sep. 2001961 inlägg
#3

Eller så gör man så att man skapar en klass för varje typ av tag som själv kan skriva ut den text som läggs in i den på rätt sätt och så sparar man alla taggar som nycklar i en HashMap och objekten som skriver ut som värdeobjekt.

139 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
136 ms — hämta tråd, inlägg och bilagor (db)