XML Libraries Support i Java

1. Introduktion

I denne artikel sammenligner vi Java XML-biblioteker og API'er.

Dette er den anden artikel fra serien om Java-understøttelse af XML, hvis du vil gå dybere ind i XPath-supporten i Java, se på den forrige artikel.

2. Oversigt

Nu skal vi grave dybere ned i XML-verdensunderstøttelsen, og for det vil vi begynde med at forklare så enkelt som muligt alle de emnerelaterede initialer.

I Java XML-support kan vi finde få API-definitioner, hver har sine fordele og ulemper.

SAX: Det er en hændelsesbaseret parsing-API, det giver adgang til lavt niveau, er hukommelseseffektiv og hurtigere end DOM, da det ikke indlæser hele dokumenttræet i hukommelsen, men det understøtter ikke navigation som den, der leveres af XPath , selvom det er mere effektivt, er det også sværere at bruge.

DOM: Det som modelbaseret parser, der indlæser et træstrukturdokument i hukommelsen, så vi har den oprindelige rækkefølge, vi kan navigere i vores dokument i begge retninger, det giver en API til læsning og skrivning, det giver XML-manipulation, og det er meget let at brug selvom prisen er stor belastning på hukommelsesressourcerne.

StAX: Det giver nem DOM og effektiviteten af ​​SAX, men det mangler en vis funktionalitet leveret af DOM som XML-manipulation, og det giver os kun mulighed for at navigere dokumentet fremad.

JAXB: Det giver os mulighed for at navigere i dokumentet i begge retninger, det er mere effektivt end DOM, det tillader konvertering fra XML til java-typer, og det understøtter XML-manipulation, men det kan kun analysere et gyldigt XML-dokument.

Du kunne stadig finde nogle referencer til JAXP, men den sidste udgivelse af dette projekt er fra marts 2013, og det er næsten dødt.

XML API-tabel

3. XML

I dette afsnit vil vi se de mest populære implementeringer, så vi kan teste reelle arbejdsprøver og kontrollere forskelle mellem dem.

I de følgende eksempler arbejder vi med en simpel XML-fil med en struktur som denne:

  Guava Introduktion til Guava 04/04/2016 Guava Forfatter ... 

4. DOM4J

Vi begynder med at se på, hvad vi kan gøre med DOM4J og til dette eksempel skal vi tilføje den sidste version af denne afhængighed.

Dette er et af de mest populære biblioteker at arbejde med XML filer, da det giver os mulighed for at udføre tovejslæsning, oprette nye dokumenter og opdatere eksisterende.

DOM4J kan arbejde med DOM, SAX, XPath og XLST. SAX understøttes via JAXP.

Lad os f.eks. Se her, hvordan kan vi vælge et element, der filtrerer efter et givet id.

SAXReader-læser = ny SAXReader (); Dokumentdokument = reader.read (fil); Listeelementer = document.selectNodes ("// * [@ tutId = '" + id + "']"); returnelementer.get (0);

Det SAXReader klasse er ansvarlig for at skabe en DOM4J træ fra SAX parsing af begivenheder. Når vi har en org.dom4j.Dokument vi skal bare kalde den nødvendige metode og videregive den til XPath udtryk som en Snor.

Vi kan indlæse et eksisterende dokument, foretage ændringer i dets indhold og derefter opdatere den originale fil.

for (Node node: nodes) {Element element = (Element) node; Iterator iterator = element.elementIterator ("titel"); mens (iterator.hasNext ()) {Element title = (Element) iterator.next (); title.setText (title.getText () + "opdateret"); }} XMLWriter-forfatter = ny XMLWriter (ny FileWriter (ny fil ("src / test / resources / example_updated.xml"))); writer.write (dokument); writer.close ();

I eksemplet ovenfor ændrer vi hver titels indhold og opretter en ny fil.

Bemærk her, hvor simpelt det er at få hver titel knude på en liste ved at ringe elementIterator og videregive navnet på knude.

Når vi har ændret vores indhold, bruger vi XMLWriter det tager en DOM4J træ og formaterer det til en strøm som XML.

Oprettelse af et nyt dokument fra bunden er så simpelt som vi ser nedenfor.

Dokumentdokument = DocumentHelper.createDocument (); Element root = document.addElement ("XMLTutorials"); Element tutorialElement = root.addElement ("tutorial"). AddAttribute ("tutId", "01"); tutorialElement.addAttribute ("type", "xml"); tutorialElement.addElement ("title"). addText ("XML med Dom4J"); ... OutputFormat format = OutputFormat.createPrettyPrint (); XMLWriter-forfatter = ny XMLWriter (ny FileWriter (ny fil ("src / test / resources / example_new.xml")), format); writer.write (dokument); writer.close (); 

DocumentHelper giver os en samling af metoder, der skal bruges af DOM4J, såsom createDocument der skaber et tomt dokument for at begynde at arbejde med det.

Vi kan oprette så mange attributter eller elementer, som vi har brug for, med de metoder, der leveres af DOM4J, og når vi har færdiggjort vores dokument, skriver vi det bare til en fil, som vi gjorde med opdateringssagen før.

5. JDOM

For at arbejde med JDOM, vi er nødt til at tilføje denne afhængighed til vores pom.

JDOM'er arbejdsstil ligner temmelig DOM4J'er, så vi vil se på et par eksempler:

SAXBuilder builder = ny SAXBuilder (); Dokument doc = builder.build (this.getFile ()); Element tutorials = doc.getRootElement (); Liste titler = tutorials.getChildren ("tutorial"); 

I eksemplet ovenfor henter vi alle elementer fra rodelementet på en meget enkel måde, som vi kan gøre med DOM4J:

SAXBuilder builder = ny SAXBuilder (); Dokumentdokument = (Dokument) builder.build (fil); Strengfilter = "// * [@ tutId = '" + id + "']"; XPathFactory xFactory = XPathFactory.instance (); XPathExpression expr = xFactory.compile (filter, Filters.element ()); List node = expr.evaluate (dokument);

Igen her i koden ovenfor har vi en SAXBuilder oprettelse af en Dokument instans fra en given fil. Vi henter et element efter dets tutId attribut ved at videregive en XPath udtryk for XPathFactory leveret af JDOM2.

6. StAX

Nu skal vi se, hvordan vi kunne hente alle elementer fra vores rodelement ved hjælp af Stax API. Stax indgår i JDK siden Java 6, så du behøver ikke tilføje afhængigheder.

For det første skal vi oprette en Vejledning klasse:

public class Tutorial {private String tutId; privat streng type; privat streng titel; privat streng beskrivelse; privat streng dato; privat strengforfatter; // standard getters og setter}

og så er vi klar til at følge med:

Liste tutorials = ny ArrayList (); XMLInputFactory fabrik = XMLInputFactory.newInstance (); XMLEventReader eventReader = factory.createXMLEventReader (ny FileReader (this.getFile ())); Vejledning nuværende; mens (eventReader.hasNext ()) {XMLEvent begivenhed = eventReader.nextEvent (); switch (event.getEventType ()) {case XMLStreamConstants.START_ELEMENT: StartElement startElement = event.asStartElement (); Streng qName = startElement.getName (). GetLocalPart (); ... pause; sag XMLStreamConstants.CHARACTERS: Tegn tegn = event.asCharacters (); ... pause; sag XMLStreamConstants.END_ELEMENT: EndElement endElement = event.asEndElement (); // kontrollere om vi fandt det afsluttende element // lukke ressourcer, der skal lukkes eksplicit; }}

I eksemplet ovenfor var vi nødt til at oprette en klasse til at gemme de hentede data i for at hjælpe os med at hente oplysningerne.

For at læse dokumentet erklærede vi, hvad der kaldes begivenhedshåndterere, og vi brugte dem til at navigere i vores dokument fremad. Husk, at SAX-implementeringerne ikke giver tovejsnavigation. Som du kan se her, skal der gøres meget arbejde bare for at hente en simpel liste over elementer.

7. JAXB

JAXB er inkluderet i JDK, såvel som Xerces, se behøver ingen ekstra afhængighed for denne.

Det er meget simpelt at indlæse, oprette og manipulere oplysninger fra en XML fil ved hjælp af JAXB.

Vi skal bare oprette de korrekte java-enheder til at binde XML og det er det.

JAXBContext jaxbContext = JAXBContext.newInstance (Tutorials.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller (); Tutorials tutorials = (Tutorials) jaxbUnmarshaller.unmarshal (this.getFile ());

I eksemplet ovenfor indlæser vi vores XML fil ind i vores objekt, og derfra kan vi håndtere alt som en normal Java-struktur;

For at oprette et nyt dokument er det så simpelt som at læse det, men gøre den omvendte måde, som det er gjort i nedenstående kode.

For det første vil vi ændre vores Vejledning klasse at tilføje JAXB kommentarer til getters og settere:

public class Tutorial {... public String getTutId () {return tutId; } @XmlAttribute public void setTutId (String tutId) {this.tutId = tutId; } ... @XmlElement public void setTitle (String title) {this.title = title; } ...} @XmlRootElement Tutorials i offentlig klasse {tutorial til privat liste; // standard getters og setters med @XmlElement-kommentar}

Med @XmlRootElement vi definerer, hvilket objekt der repræsenterer rodnoden i vores dokument, og så bruger vi @XmlAttribut eller @XmlElement for at definere, om denne attribut repræsenterer en attribut for en node eller et element i dokumentet.

Så kan vi følge med:

Tutorials tutorials = nye Tutorials (); tutorials.setTutorial (ny ArrayList ()); Tutorial tut = ny tutorial (); tut.setTutId ("01"); ... tutorials.getTutorial (). tilføj (tut); JAXBContext jaxbContext = JAXBContext.newInstance (Tutorials.class); Marshaller jaxbMarshaller = jaxbContext.createMarshaller (); jaxbMarshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, sandt); jaxbMarshaller.marshal (tutorials, fil);

Som du kan se, er binding af XML-fil til Java-objekter den nemmeste måde at arbejde på denne type filer.

8. XPath Expression Support

For at oprette komplekse XPath-udtryk kan vi bruge Jaxen. Dette er et open source XPath-bibliotek, der kan tilpasses til mange forskellige objektmodeller, herunder DOM, XOM, DOM4Jog JDOM.

Vi kan oprette XPath-udtryk og kompilere dem mod mange understøttede dokumenter.

String expression = "/ tutorials / tutorial"; XPath-sti = ny DOMXPath (udtryk); Listeresultat = sti.selectNodes (xmlDocument);

For at få det til at fungere bliver vi nødt til at tilføje denne afhængighed til vores projekt.

9. Konklusion

Som du kan se, er der mange muligheder for at arbejde med XML, afhængigt af kravene i din applikation, kan du arbejde med en hvilken som helst af dem, eller du skal muligvis vælge mellem effektivitet og enkelhed.

Du kan finde de fulde arbejdsprøver til denne artikel i vores git-arkiv her.