Raščlanjivanje XML datoteke pomoću SAX parsera

1. Pregled

SAX, također poznat kao jednostavni API za XML, koristi se za raščlanjivanje XML dokumenata.

U ovom uputstvu naučit ćemo što je SAX i zašto, kada i kako ga treba koristiti.

2. SAKSOFON: Jednostavni API za XML

SAX je API koji se koristi za raščlanjivanje XML dokumenata. To temelji se na događajima generirano tijekom čitanja dokumenta. Metode povratnog poziva primaju te događaje. Prilagođeni rukovatelj sadrži te metode povratnog poziva.

API je učinkovit jer ispušta događaje odmah nakon primanja povratnih poziva. Stoga, SAX ima učinkovito upravljanje memorijom, za razliku od DOM-a, na primjer.

3. SAX protiv DOM-a

DOM je skraćenica od Document Object Model. The DOM parser se ne oslanja na događaje. Štoviše, učitava cijeli XML dokument u memoriju kako bi ga raščlanio. SAX je memorijski učinkovitiji od DOM-a.

DOM ima i svoje prednosti. Na primjer, DOM podržava XPath. Od tada to također olakšava rad na cijelom stablu dokumenata odjednom dokument se učitava u memoriju.

4. SAX vs StAX

StAX je noviji od SAX-a i DOM-a. Zalaže se za API za strujanje za XML.

Glavna razlika sa SAX-om je u tome StAX koristi vučni mehanizam umjesto SAX-ovog potisnog mehanizma (pomoću povratnih poziva).

To znači da se klijentu daje kontrola da odluči kada događaje treba povući. Stoga nema obveze povlačenja cijelog dokumenta ako je potreban samo njegov dio.

Pruža jednostavan API za rad s XML-om s memorijski učinkovitim načinom raščlanjivanja.

Za razliku od SAX-a, on ne nudi provjeru valjanosti sheme kao jednu od svojih značajki.

5. Raščlanjivanje XML datoteke pomoću prilagođenog rukovatelja

Koristimo sada sljedeći XML koji predstavlja web mjesto Baeldung i njegove članke:

   Raščlanjivanje XML datoteke pomoću SAX parsera SAX Parser Lorem ipsum ... Raščlanjivanje XML datoteke pomoću DOM parsera DOM Parser Lorem ipsum ... Raščlanjivanje XML datoteke pomoću StAX Parser StAXova Lorem ipsum ... 

Počet ćemo s izradom POJO-a za naše Baeldung korijenski element i njegova djeca:

javna klasa Baeldung {private list articleList; // uobičajeni geteri i postavljači} 
javna klasa BaeldungArticle {naslov privatnog niza; privatni sadržaj niza; // uobičajeni geteri i postavljači} 

Nastavit ćemo s izradom BaeldungHandler. Ova će klasa implementirati metode povratnog poziva potrebne za bilježenje događaja.

Zamijenit ćemo četiri metode iz superklase DefaultHandler, svaki koji karakterizira događaj:

    • znakovi (char [], int, int) prima likove s granicama. Pretvorit ćemo ih u Niz i pohranite ga u varijablu od BaeldungHandler
    • startDocument () poziva se kad raščlanjivanje započne - upotrijebit ćemo ga za konstrukciju našeg Baeldung primjer
    • startElement () poziva se kada raščlanjivanje elementa započne - koristit ćemo ga za konstrukciju Popis ili BaeldungArticle slučajevi - qIme pomaže nam napraviti razliku između obje vrste
    • endElement () poziva se kad raščlanjivanje elementa završi - tada ćemo dodijeliti sadržaj oznaka njihovim odgovarajućim varijablama

Sa svim definiranim povratnim pozivima, sada možemo napisati BaeldungHandler razred:

javna klasa BaeldungHandler proširuje DefaultHandler {private static final String ARTICLES = "articles"; privatni statički završni niz ČLANAK = "article"; privatni statički konačni niz TITLE = "title"; privatni statički konačni niz SADRŽAJ = "sadržaj"; privatno web mjesto Baeldung; private String elementValue; @Preuzmi javne praznine (char [] ch, int start, int length) baca SAXException {elementValue = novi niz (ch, start, length); } @Override public void startDocument () baca SAXException {web mjesto = novo Baeldung (); } @Override public void startElement (String uri, String lName, String qName, Atributi attr) baca SAXException {switch (qName) {case ČLANCI: website.articleList = new ArrayList (); pauza; slučaj ČLANAK: website.articleList.add (novi BaeldungArticle ()); }} @Override public void endElement (String uri, String localName, String qName) baca SAXException {prekidač (qName) {case TITLE: latestArticle (). Title = elementValue; pauza; case SADRŽAJ: latestArticle (). content = elementValue; pauza; }} private BaeldungArticle latestArticle () {List articleList = website.articleList; int latestArticleIndex = articleList.size () - 1; vrati articleList.get (latestArticleIndex); } javni Baeldung getWebsite () {return web mjesto; }} 

Dodane su i konstante niza kako bi se povećala čitljivost. Prikladna je i metoda za pronalaženje najnovijeg članka s kojim je došlo. Napokon, treba nam getter za Baeldung objekt.

Imajte na umu da gore navedeno nije sigurno, jer držimo stanje između poziva metode.

6. Testiranje parsera

Da bismo testirali parser, instancirat ćemo SaxFactory, SaxParser a također i BaeldungHandler:

Tvornica SAXParserFactory = SAXParserFactory.newInstance (); SAXParser saxParser = factory.newSAXParser (); SaxParserMain.BaeldungHandler baeldungHandler = novo SaxParserMain.BaeldungHandler (); 

Nakon toga ćemo raščlaniti XML datoteku i ustvrditi da objekt sadrži sve raščlanjene očekivane elemente:

saxParser.parse ("src / test / resources / sax / baeldung.xml", baeldungHandler); Rezultat SaxParserMain.Baeldung = baeldungHandler.getWeb (); assertNotNull (rezultat); Popis članaka = result.getArticleList (); assertNotNull (članci); assertEquals (3, articles.size ()); SaxParserMain.BaeldungArticle articleOne = articles.get (0); assertEquals ("Raščlanjivanje XML datoteke pomoću SAX parsera", articleOne.getTitle ()); assertEquals ("SAX Parser's Lorem ipsum ...", articleOne.getContent ()); SaxParserMain.BaeldungArticle articleTwo = articles.get (1); assertEquals ("Raščlanjivanje XML datoteke pomoću DOM Parsera", articleTwo.getTitle ()); assertEquals ("Lorem ipsum DOM Parsera ...", articleTwo.getContent ()); SaxParserMain.BaeldungArticle articleThree = articles.get (2); assertEquals ("Raščlanjivanje XML datoteke pomoću StAX Parsera", articleThree.getTitle ()); assertEquals ("Lorex ipsum parsera StAX Parsera ...", articleThree.getContent ()); 

Očekivano, baeldung ispravno je raščlanjen i sadrži očekivane pod-objekte.

7. Zaključak

Upravo smo otkrili kako koristiti SAX za raščlanjivanje XML datoteka. To je moćan API koji generira mali trag memorije u našim aplikacijama.

Kao i obično, kôd za ovaj članak dostupan je na GitHubu.