Ohjelmointi

XML: n ohjelmointi Java-ohjelmassa, osa 1

Joten ymmärrät (enemmän tai vähemmän), miten edustaisit tietojasi XML: ssä, ja olet kiinnostunut XML: n avulla ratkaisemaan monia tiedonhallintaongelmia. Et kuitenkaan ole varma, kuinka XML: ää käytetään Java-ohjelmiesi kanssa.

TEXTBOX: TEXTBOX_HEAD: XML: n ohjelmointi Java: ssa: Lue koko sarja!

  • Osa 1. Käytä XML: n yksinkertaista sovellusliittymää (SAX) XML: n käsittelyyn Java-sovelluksessa helposti
  • Osa 2. Tutustu SAX- ja XML-validointiin havainnollistavien esimerkkien avulla
  • Osa 3. DOMinaatio: Ohjaa jäsenneltyjä asiakirjoja Document Object Model -sovelluksella

: END_TEXTBOX

Tämä artikkeli on jatkoa huhtikuussa 1999 julkaistulle aloitusartikkelilleni "XML absoluuttiselle aloittelijalle". JavaWorld (katso URL-osoite alla olevasta Resurssit-osiosta). Tässä artikkelissa kuvattiin XML; Rakennan nyt tätä kuvausta ja näytän yksityiskohtaisesti, kuinka luodaan sovellus, joka käyttää yksinkertaista Java-sovellusliittymää (SAX), joka on kevyt ja tehokas standardi Java-sovellusliittymä XML: n käsittelyyn.

Tässä käytetty esimerkkikoodi käyttää SAX-sovellusliittymää XML-tiedoston lukemiseen ja hyödyllisen objektirakenteen luomiseen. Kun olet kirjoittanut tämän artikkelin, olet valmis luomaan omat XML-pohjaiset sovelluksesi.

Laiskan hyve

Larry Wall, Perlin (olemassaolon toiseksi suurin ohjelmointikieli) hullu nerokas luoja, on todennut, että laiskuus on yksi ohjelmoijan "kolmesta suuresta hyveestä" (kaksi muuta ovat kärsimättömyys ja hubris). Laisuus on hyve, koska laiska ohjelmoija menee melkein mihin tahansa välttääkseen työtä, jopa siinä määrin, että se luo yleiset, uudelleenkäytettävät ohjelmointikehykset, joita voidaan käyttää toistuvasti. Tällaisten kehysten luominen vaatii paljon työtä, mutta tuleviin tehtäviin säästetty aika ylittää alkuperäisen panostuksen. Parhaat kehykset antavat ohjelmoijien tehdä hämmästyttäviä asioita vain vähän tai ei lainkaan - ja siksi laiskuus on hyveellistä.

XML on hyödyllinen tekniikka hyveelliselle (laiska) ohjelmoijalle. Perus XML-jäsennin tekee paljon työtä ohjelmoijalle, tunnistaa tunnukset, kääntää koodatut merkit, valvoo XML-tiedostorakenteen sääntöjä, tarkistaa joidenkin data-arvojen oikeellisuuden ja kutsuu tarvittaessa sovelluskohtaista koodia. Itse asiassa varhainen standardointi yhdistettynä kovan kilpailun omaavaan markkinapaikkaan on tuottanut lukuisia vapaasti saatavilla olevat vakiomuotoisten XML-jäsentimien toteutukset monilla kielillä, mukaan lukien C, C ++, Tcl, Perl, Python ja tietysti Java.

SAX-sovellusliittymä on yksi yksinkertaisimmista ja kevyimmistä käyttöliittymistä XML: n käsittelemiseen. Tässä artikkelissa käytän IBM: n SAX: n XML4J-toteutusta, mutta koska sovellusliittymä on standardoitu, sovelluksesi voi korvata minkä tahansa paketin, joka toteuttaa SAX: n.

SAX on tapahtumapohjainen sovellusliittymä, joka toimii takaisinsoiton periaatteella. Sovellusohjelmoija luo tyypillisesti SAX: n Jäsennin ja välitä se sekä XML-syötteen että a asiakirjojen käsittelijä, joka vastaanottaa takaisinsoittoja SAX-tapahtumista. SAX Jäsennin muuntaa syötteensä Tapahtumat jotka vastaavat syötteen rakenteellisia ominaisuuksia, kuten XML-tunnisteita tai tekstilohkoja. Kunkin tapahtuman tapahtuessa se välitetään ohjelmoijan määrittelemän asiakirjankäsittelijän sopivalle menetelmälle, joka toteuttaa takaisinsoittorajapinnan org.xml.sax.DocumentHandler. Tämän käsittelijäluokan menetelmät suorittavat sovelluskohtaiset toiminnot jäsentämisen aikana.

Kuvittele esimerkiksi, että SAX-jäsennin vastaanottaa asiakirjan, joka sisältää pienen XML-asiakirjan, joka näkyy alla olevassa luettelossa 1. (Katso XML-tiedoston resurssit.)

 Ogden Nash Kirput Adam oli heidän. 

Listaus 1. XML, joka edustaa lyhyttä runoa

Kun SAX-jäsennin kohtaa -tunniste, se kutsuu käyttäjän määrittelemää DocumentHandler.startElement () merkkijonolla RUNO argumenttina. Toteutat startElement () menetelmä tehdä mitä tahansa sovellusta on tarkoitus tehdä, kun a RUNO alkaa. Edellä olevan XML-osan tapahtumavirta ja siitä johtuvat puhelut näkyvät alla olevassa taulukossa 1.

Taulukko 1. Takaisinsoittojen järjestys, jonka SAX tuottaa listaten 1 jäsentämisen aikana
Kohde havaittuParser-soittopyyntö
{Asiakirjan alku}startDocument ()
startElement ("RUNKO", {AttributeList})
"\ n"merkkiä ("\ n ...", 6, 1)
startElement ("AUTHOR", {AttributeList})
"Ogden Nash"merkkiä ("\ n ...", 15, 10)
endElement ("AUTHOR")
"\ n"merkkiä ("\ n ...", 34, 1)
startElement ("TITLE", {AttributeList})
"Kirput"merkkiä ("\ n ...", 42, 5)
endElement ("TITLE")
"\ n"merkkiä ("\ n ...", 55, 1)
startElement ("LINE", {AttributeList})
"Adam"merkkiä ("\ n ...", 62, 4)
endElement ("LINE")
startElement ("LINE", {AttributeList})
"Oli heitä."merkkiä ("\ n ...", 67, 8)
endElement ("LINE")
"\ n"merkkiä ("\ n ...", 82, 1)
endElement ("RUNKO")
{Asiakirjan loppu}endDocument ()

Luod luokan, joka toteuttaa DocumentHandler vastaamaan SAX-jäsentimessä tapahtuviin tapahtumiin. Nämä Tapahtumat eivät ole Java-tapahtumia, koska saatat tuntea ne Abstract Windowing Toolkitista (AWT). Ne ovat ehtoja, jotka SAX-jäsennin havaitsee jäsennellessään, kuten asiakirjan alku tai sulkevan tunnisteen esiintyminen syötevirrassa. Kun jokainen näistä ehdoista (tai tapahtumista) tapahtuu, SAX kutsuu ehtoa vastaavaa menetelmää DocumentHandler.

Joten, avain XML: ää SAX: lla käsittelevien ohjelmien kirjoittamiseen on selvittää mitä DocumentHandler pitäisi tehdä vastauksena SAX: n menetelmän takaisinkutsuihin. SAX-jäsennin huolehtii tunnisteiden tunnistamisen, entiteettiarvojen korvaamisen ja niin edelleen, jolloin sinulla on mahdollisuus keskittyä sovelluskohtaisiin toimintoihin, jotka käyttävät XML: ään koodattuja tietoja.

Taulukko 1 näyttää vain tapahtumiin liittyvät elementit ja merkit. SAX sisältää myös palveluja XML-tiedostojen muiden rakenteellisten ominaisuuksien, kuten entiteettien ja käsittelyohjeiden, käsittelyyn, mutta nämä eivät kuulu tämän artikkelin piiriin.

Älykäs lukija huomaa, että XML-asiakirja voidaan esittää kirjoitettujen objektien puuna ja että tapahtumavirran järjestys DocumentHandler vastaa asiakirjan puun oikeassa syvyydessä tapahtuvaa läpikulkua. (Ei ole välttämätöntä ymmärtää tätä kohtaa, mutta XML-asiakirjan käsite puupohjaisena tietorakenteena on hyödyllinen kehittyneemmissä asiakirjojen käsittelytyypeissä, joita käsitellään tämän sarjan myöhemmissä artikkeleissa.)

Avain SAX: n käytön ymmärtämiseen on DocumentHandler käyttöliittymä, josta keskustelen seuraavaksi.

Muokkaa jäsennintä org.xml.sax.DocumentHandlerilla

Koska DocumentHandler käyttöliittymä on niin keskeinen XML: n käsittely SAX: n kanssa, kannattaa ymmärtää, mitä käyttöliittymän menetelmät tekevät. Käsittelen tässä osassa olennaiset menetelmät ja ohitan ne, jotka käsittelevät edistyneempiä aiheita. Muistaa, DocumentHandler on käyttöliittymä, joten kuvaamani menetelmät ovat menetelmiä, jotka otat käyttöön sovelluskohtaisten toimintojen käsittelemiseksi aina, kun vastaava tapahtuma tapahtuu.

Asiakirjan alustaminen ja siivous

SAX XML-jäsennin kutsuu kutakin jäsennettyä asiakirjaa DocumentHandler rajapintamenetelmät startDocument () (soitettu ennen käsittelyn aloittamista) ja endDocument () (kutsutaan käsittelyn päätyttyä). Voit käyttää näitä menetelmiä alustamaan DocumentHandler valmistella se tapahtumien vastaanottamiseen ja siivoamaan tai tuottamaan tulos jäsentämisen jälkeen. endDocument () on erityisen mielenkiintoinen, koska sitä kutsutaan vain, jos syötedokumentti on jäsennetty onnistuneesti. Jos Jäsennin aiheuttaa kohtalokkaan virheen, se yksinkertaisesti keskeyttää tapahtumavirran ja lopettaa jäsentämisen ja endDocument () ei koskaan soiteta.

Käsitellään tunnisteita

SAX-jäsennin kutsuu startElement () aina kun se havaitsee avoimen tunnisteen, ja endElement () aina kun se havaitsee läheisen tunnisteen. Nämä menetelmät sisältävät usein koodin, joka tekee suurimman osan työstä jäsennettäessä XML-tiedostoa. startElement ()Ensimmäinen argumentti on merkkijono, joka on havaitun elementin tagin nimi. Toinen argumentti on tyypin kohde AttributeList, paketissa määritetty käyttöliittymä org.xml.sax joka tarjoaa peräkkäisen tai satunnaisen pääsyn elementtimääritteisiin nimen mukaan. (Olet epäilemättä nähnyt määritteitä aiemmin HTML-muodossa; rivillä

, Raja on attribuutti, jonka arvo on "1"). Koska luettelossa 1 ei ole määritteitä, ne eivät näy taulukossa 1. Näet esimerkkejä määritteistä esimerkkisovelluksessa myöhemmin tässä artikkelissa.

Koska SAX ei anna mitään tietoja kohtaamiensa elementtien kontekstista (se ilmestyy sisälle esimerkiksi luettelossa 1 yllä), sinun on annettava nämä tiedot. Sovellusohjelmoijat käyttävät usein pinoja startElement () ja endElement (), työntämällä esineitä pinolle, kun elementti alkaa, ja pudottamalla ne pinosta, kun elementti loppuu.

Käsittele tekstilohkot

merkkiä () method osoittaa XML-asiakirjan merkisisällön - merkit, jotka eivät näy XML-tagissa, toisin sanoen. Tämän menetelmän allekirjoitus on vähän outo. Ensimmäinen argumentti on tavujoukko, toinen on hakemisto tähän ryhmään, joka ilmaisee käsiteltävän alueen ensimmäisen merkin, ja kolmas argumentti on merkkialueen pituus.

Saattaa tuntua, että helpompi sovellusliittymä olisi yksinkertaisesti läpäissyt a Merkkijono objekti, joka sisältää tiedot, mutta merkkiä () määriteltiin tällä tavalla tehokkuussyistä. Parserilla ei ole mitään tapaa tietää, aiotko käyttää merkkejä vai ei, joten kun jäsentäjä jäsentää syöttöpuskurinsa, se välittää viittauksen puskuriin ja tarkasteltavan merkkijonon indekseihin luottaen siihen, että rakennat omasi Merkkijono jos haluat sellaisen. Se on vähän enemmän työtä, mutta sen avulla voit päättää, aiheutetaanko yleiskustannukset Merkkijono XML-tiedoston sisältökappaleiden rakenne.

merkkiä () method käsittelee sekä tavallista tekstisisältöä että sisältöä CDATA-osioissa, joita käytetään estämään kirjaimellisen tekstin lohkojen jäsentämistä XML-jäsentimen toimesta.

Muut menetelmät

Ohjelmassa on kolme muuta menetelmää DocumentHandler käyttöliittymä: tietämätönWhitepace (), käsittelyohjeet ()ja setDocumentLocator (). tietämätönWhitepace () ilmoittaa välilyönnin esiintymät, ja sitä ei yleensä käytetä validoimattomissa SAX-jäsennöissä (kuten tässä artikkelissa käyttämämme); käsittelyohjeet () käsittelee useimmat asiat sisällä ja ?> erotimet; ja setDocumentLocator () on valinnaisesti SAX-jäsentäjien käyttöön antamaan sinulle pääsyn SAX-tapahtumien sijainteihin alkuperäisessä tulovirrassa. Voit lukea nämä menetelmät seuraamalla resurssien SAX-rajapintojen linkkejä.

Kaikkien menetelmien toteuttaminen käyttöliittymässä voi olla työlästä, jos olet kiinnostunut vain yhden tai kahden käyttäytymisestä. SAX-paketti sisältää luokan nimeltä HandlerBase se ei periaatteessa tee mitään, mutta voi auttaa sinua hyödyntämään vain yhtä tai kahta näistä menetelmistä. Tarkastellaan tätä luokkaa tarkemmin.

HandlerBase: Ei-mitään-luokka

Usein olet kiinnostunut vain yhden tai kahden menetelmän toteuttamisesta käyttöliittymässä ja haluat, että muut menetelmät eivät yksinkertaisesti tee mitään. Luokka org.xml.sax.HandlerBase yksinkertaistaa DocumentHandler käyttöliittymä toteuttamalla kaikki käyttöliittymän menetelmät tekemättä mitään -elimillä. Sitten sen sijaan, että toteutettaisiin DocumentHandler, voit alaluokka HandlerBaseja ohita vain sinua kiinnostavat menetelmät.

Oletetaan esimerkiksi, että haluat kirjoittaa ohjelman, joka vain tulosti minkä tahansa XML-muotoisen runon nimen (kuten TitleFinder luettelossa 1). Voit määrittää uuden DocumentHandler, kuten alla olevassa luettelossa 2, tämä alaluokka HandlerBase, ja ohittaa vain tarvitsemasi menetelmät. (Katso Resurssit HTML-tiedostolle TitleFinder.)

012 / ** 013 * SAX DocumentHandler -luokka, joka tulostaa tulodokumentin "TITLE" -elementin 014 * sisällön. 015 * / 016 public class TitleFinder laajentaa HandlerBase {017 looginen _isTitle = false; 018 julkista TitleFinder () {019 super (); 020} 021 / ** 022 * Tulosta teksti, joka löytyy a  elementti. 023 * / 024 julkista tyhjää merkkiä (char [] merkit, int iStart, int iLen) {025 if (_isTitle) {026 String sTitle = uusi merkkijono (merkit, iStart, iLen); 027 System.out.println ("Otsikko:" + sTitle); 028} 029} 030 / ** 031 * Merkitse otsikkoelementin loppu. 032 * / 033 public void endElement (Merkkijono-elementti) {034 if (element.equals ("TITLE")) {035 _isTitle = false; 036} 037} 038 / ** 039 * Etsi otsikoiden sisältö 040 * / 041 public static void main (String args []) {042 TitleFinder titleFinder = new TitleFinder (); 043 kokeile {044 Parser parser = ParserFactory.makeParser ("com.ibm.xml.parsers.SAXParser"); 045 parser.setDocumentHandler (titleFinder); 046 parser.parse (uusi InputSource (argumentit [0])); 047} saalis (poikkeus ex) {048; // OK, joten joskus laiskuus * ei ole hyve. 049} 050} 051 / ** 052 * Merkitse otsikkoelementin alku 053 * / 054 public void startElement (String element, AttributeList attrlist) {055 if (element.equals ("TITLE")) {056 _isTitle = true; 057} 058} 

Listaus 2. TitleFinder: HandlerBasesta johdettu DocumentHandler, joka tulostaa TITLEs

Copyright fi.verticalshadows.com 2022