bild
Skolan för
datorvetenskap
och kommunication

Labb 1 »
Labb 2 »
Labb 4 »
Labb 5 »
Labb 6 »

KTH / CSC / DD1346

Labb 3, XML och textbehandling

Målet med denna labb är att introducera XML-formatet, och titta på hur man kan använda det till att lagra och läsa in hierarkiskt organiserad information. I denna labb tar vi ett färdigt program med en viss funktion, och ändrar det till att utföra en annan funktion.

Del E

För godkänt till betyg E på denna labb krävs att samtliga uppgifter i denna del skall vara utförda, samt att båda i labbgruppen kan förklara resonemanget bakom lösningarna och hur koden fungerar.

E1. En trädvisare

I denna lab ska vi ta ett program som kan visa filhierarkier och ändra det till att kunna läsa in en annan hierarki från en XML-fil och visa den i stället. Det första steget blir att ladda ner källkoden för DirTree.java och bekanta sig med den. Boken Object-oriented programming in Java av Martin Kalin har tidigare använts som kursbok på DD2385. I boken finns ett program som skriver ut filkatalogträd med hjälp av en avancerad swingkomponent, JTree. Koden i länken ovan är en modifierad version av detta.

Uppgift E1.1 Bekanta er med koden för DirTree. Se till att ni förstår vad programmets olika delar gör. Kompilera koden och kör den. Om allting fungerar borde ni se ett träd som visar katalogstrukturen där ni står. Om det inte finns några underkataloger i er aktuella katalog kan det se lite tråkigt ut. Försök till exepel med:

java DirTree /info/DD1346

Detta kommer att visa katalogstrukturen från kursens hemkatalog, som förhoppningsvis har lite fler underkataloger att titta på. Prova gärna på någon lokal katalog på er egen dator om det går för långsamt.
Uppgift E1.2 Modifiera programmet så att det visar ett helt annat träd, nämligen livsträdet. I trädets rot ska det stå Liv och roten ska ha tre barn, Växter, Djur och Svampar som i sin tur innehåller ordningar, underordningarn familjer, släkten och arter. I rotnoden ska ordet "Liv" stå, inte katalognamnet. I metoden buildTree() suddar ni allt och skriver nya satser som tillverkar en nod child på samma sätt som rotnoden men med texten Växter. Addera den till trädmodellen med root som förälder. Gör likadant med djur och svampar.

E2. Inmatning via XML

Rekommenderad läsning: XML, scanning och String

Om man har väldigt mycket data är det förstås onödigt omständligt att behöva skriva in alla posterna manuellt i källkoden, och svårt för den som vill ändra något i efterhand. I detta moment ska ni läsa in data från en XML-fil för att på ett enkel sätt kunna bygga upp ett lite större hierarkiskt träd.

Länken ovan leder till en presentation av XML hos W3C, som innehåller länkar och intressant läsning för den som vill fördjupa sig i XML. Det finns också en väldigt kortfattad introduktion till XML för den som bara vill få en snabb och översiktligt bild.

För att skapa livsträdet i den här labben ska ni läsa in data från filen Liv.xml. Titta igenom filen och set till att ni förstår hur den är uppbyggd. En mer överskådlig miniversion finns i filen LillaLiv.txt.

Uppgift E2.1Förutom nodens namn finns det nu också en nivå (t.ex Rike) och en förklarande text. För dessa finns ingen plats i klassen DefaultMutableTreeNode. Skriv därför en egen subklass MyNode som innehåller String-variablerna level och text.


Nästa steg blir att läsa in data från filen och använda denna till att skapa noder. Det enklaste sättet är att använda sig av klassen Scanner, och antingen läsa in ett ord i taget med next eller en hel rad i taget med nextLine. Tänk på att det nästade anropet av new File("Life.xml") kan slänga ur sig en FileNotFoundException som måste fångas. Ni får anta att XML-filen är felfri och att den följer mönstret att filen är radindelad med en tag per rad som i exempelfilerna och att det är exakt ett blanktecken mellan nivån och ordet namn (som t.ex <Biosfär namn="Liv">) samt inga blanktecken alls på andra ställen utom i den förklarande texten i slutet av raderna. Dock ska er kod fungera lika bra om den matas med en annan XML-fil av samma typ men med fler eller färre nivåer av noder.

Uppgift E2.2 Skriv en metod readNode() som returnerar en MyNode. Metoden ska börja läsa på aktuell rad i Scanner-objektet och skapa en ny nod retNode baserat på de data som finns där. Sen ska den:
  1. låta Scanner-objektet fortsätta till nästa rad.
  2. Om denna rad innehåller sluttagen som passar ihop med starttagen som metodanropet började på, ska den fortsätta till nästa rad och returnera retNod. Om raden innehåller en ny starttag ska den anropa sig själv rekursivt på denna rad, och lägga till den returnerade noden som ett barn till retNode.
  3. Gå till punkt 1.
Ni bör nu kunna skapa hela trädet genom att anropa

root=readNode();

Ett sätt att ta sig igenom en textfil är att använda nextLine till att skapa en String, som man sedan använder för att skapa ett nytt Scanner-objekt som bara är verksamt på just den raden. Sedan kan man hitta element i den strängen med hjälp av den "innre" Scannerns next- eller nextLine- metoder. Dessa metoder kommer att inkludera en del tecken vi inte är intresserade av, men man kan plocka ut de intressanta delsträngarna med hjälp av String.substring(int begin, int end). För att se om en sträng börjar med en intressant teckenkombination (t.ex "</") så kan man använda metoden String.startsWith(String s).
Uppgift E2.3 I det ursprungliga programmet får man filupplysningar om "Show details" förkryssas. I ert program ska man i stället få se den förklarande texten, till exempel Art: Mås gillar Vaxholmsbåtar. Fixa så att showDetails(TreePath p) lägger ut denna text i sin JOptionPane.

Del C

För godkänt till betyg C på denna labb krävs - utöver godkänd E-del - att samtliga uppgifter i denna del skall vara utförda, samt att båda i labbgruppen kan förklara hur koden fungerar, och varför ni löste problemen som ni gjorde.
Uppgift C1 Ordna så att man förutom grundinformationen av typen "Art: Mås gillar Vaxholmsbåtar", också får hela kedjan av namn utskriven på formen "men allt som är Mås är Fåglar är Djur är Liv". Användbar metod i TreePath är getLastPathComponent(). I DefaultMutableTreeNode och därmed i MyNode finns metoden getParent(). Det finns även andra metoder som löser uppgiften.
Uppgift C2 Låt koden som parsar XML-filen reagera på fel. readNode() ska slänga ett lämpligt fel om XML-filen inte går att parsa. Exempel pa saker som er kod bör reagera på är mismatchade start- och sluttaggar, taggar som saknar avslutande '>'-tecken, omatchade citationstecken, m.m. Er kod behöver inte skilja på typen av fel eller kunna identifiera fler än ett fel i en fil; det räcker att avbryta parsningen och meddela att någonting var fel med filen. Lästips: Exceptions.
Sidansvarig: Christian Smith <ccs@kth.se>
Uppdaterad 2011-05-20