Java >> Java tutorial >  >> Tag >> XML

XML Libraries Support i Java

1. Introduktion

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

Dette er den anden artikel fra serien om Java-understøttelse til XML, hvis du vil gå dybere ind i XPath-understøttelsen i Java, så kig i den forrige artikel.

2. Oversigt

Nu skal vi grave dybere ned i XML-verdenens support, og til det vil vi starte med at forklare alle de emnerelaterede initialer så enkelt som muligt.

I Java XML-understøttelse kan vi finde få API-definitioner, hver enkelt har sine fordele og ulemper.

SAX :Det er et hændelsesbaseret parsing-API, det giver adgang på lavt niveau, er hukommelseseffektivt og hurtigere end DOM, da det ikke indlæser hele dokumenttræet i hukommelsen, men det giver ikke understøttelse af navigation som det, 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 originale elementrækkefølge, vi kan navigere i vores dokument i begge retninger, den giver en API til læsning og skrivning, den tilbyder XML-manipulation, og det er meget nemt at bruge, selvom prisen belaster hukommelsesressourcerne meget.

StAX :Det tilbyder den nemme DOM og effektiviteten af ​​SAX, men den 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 parse et gyldigt XML-dokument.

Du kan stadig finde nogle referencer til JAXP, men sidste udgivelse af dette projekt er fra marts 2013, og det er praktisk talt dødt.

XML API-tabel

3. XML

I dette afsnit skal vi se de mest populære implementeringer, så vi kan teste rigtige arbejdseksempler og kontrollere forskelle mellem dem.

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

<tutorials>
    <tutorial tutId="01" type="java">
        <title>Guava</title>
        <description>Introduction to Guava</description>
        <date>04/04/2016</date>
        <author>GuavaAuthor</author>
    </tutorial>
    ...
</tutorials>

4. DOM4J

Vi vil starte med at tage et kig på, hvad vi kan gøre med DOM4J og for 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 tage et kig her for eksempel, hvordan kan vi vælge et element, der filtrerer efter et givet id.

SAXReader reader = new SAXReader();
Document document = reader.read(file);
List<Node> elements = document.selectNodes("//*[@tutId='" + id + "']");
return elements.get(0);

SAXReader klasse er ansvarlig for at oprette en DOM4J træ fra SAX parsing af begivenheder. Når vi har et org.dom4j.Document vi skal bare kalde den nødvendige metode og sende XPath til den udtryk som en streng.

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<Element> iterator = element.elementIterator("title");
    while (iterator.hasNext()) {
        Element title =(Element)iterator.next();
        title.setText(title.getText() + " updated");
    }
}
XMLWriter writer = new XMLWriter(
  new FileWriter(new File("src/test/resources/example_updated.xml")));
writer.write(document);
writer.close();

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

Bemærk her, hvor nemt det er at få hver titels node på en liste ved at kalde elementIterator og sender navnet på noden.

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

At oprette et nyt dokument fra bunden er lige så enkelt, som vi kan se nedenfor.

Document document = DocumentHelper.createDocument();
Element root = document.addElement("XMLTutorials");
Element tutorialElement = root.addElement("tutorial").addAttribute("tutId", "01");
tutorialElement.addAttribute("type", "xml");
tutorialElement.addElement("title").addText("XML with Dom4J");
...
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(
  new FileWriter(new File("src/test/resources/example_new.xml")), format);
writer.write(document);
writer.close();

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

Vi kan oprette så mange attributter eller elementer, som vi har brug for, med metoderne leveret 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 arbejdsstilen er ret lig DOM4J's , så vi tager et kig på et par eksempler:

SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(this.getFile());
Element tutorials = doc.getRootElement();
List<Element> titles = 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 = new SAXBuilder();
Document document = (Document) builder.build(file);
String filter = "//*[@tutId='" + id + "']";
XPathFactory xFactory = XPathFactory.instance();
XPathExpression<Element> expr = xFactory.compile(filter, Filters.element());
List<Element> node = expr.evaluate(document);

Igen, her i koden ovenfor, har vi en SAXBuilder oprettelse af et Dokument instans fra en given fil. Vi henter et element ved dets tutId attribut ved at sende en XPath udtryk til 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 er inkluderet i JDK siden Java 6, så du behøver ikke tilføje nogen afhængigheder.

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

public class Tutorial {
    private String tutId;
    private String type;
    private String title;
    private String description;
    private String date;
    private String author;
    
    // standard getters and setters
}

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

List<Tutorial> tutorials = new ArrayList<>();
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLEventReader eventReader = factory.createXMLEventReader(new FileReader(this.getFile()));
Tutorial current;
while (eventReader.hasNext()) {
    XMLEvent event = eventReader.nextEvent();
    switch (event.getEventType()) {
        case XMLStreamConstants.START_ELEMENT:
            StartElement startElement = event.asStartElement();
            String qName = startElement.getName().getLocalPart();
            ...
            break;
        case XMLStreamConstants.CHARACTERS:
            Characters characters = event.asCharacters();
            ...
            break;
        case XMLStreamConstants.END_ELEMENT:
            EndElement endElement = event.asEndElement();
            
            // check if we found the closing element
            // close resources that need to be explicitly closed
            break;
    }
}

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

For at læse dokumentet erklærede vi det, der kaldes hændelseshandlere, og vi brugte dem til at navigere 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, behøver se ikke nogen ekstra afhængighed for denne.

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

Vi skal bare oprette de korrekte java-enheder for 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 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 at gøre den omvendte måde, som i nedenstående kode.

For det første skal vi ændre vores Tutorial klasse for at tilføje JAXB annoteringer til getters og sættere :

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
public class Tutorials {
    private List<Tutorial> tutorial;

    // standard getters and setters with @XmlElement annotation
}

Med @XmlRootElement vi definerer hvilket objekt der skal repræsentere rodknudepunktet i vores dokument, og derefter bruger vi @XmlAttribute 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 = new Tutorials();
tutorials.setTutorial(new ArrayList<>());
Tutorial tut = new Tutorial();
tut.setTutId("01");
...
tutorials.getTutorial().add(tut);
JAXBContext jaxbContext = JAXBContext.newInstance(Tutorials.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(tutorials, file);

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

8. XPath Expression Support

For at skabe komplekse XPath-udtryk kan vi bruge Jaxen. Dette er et open source XPath-bibliotek, der kan tilpasses til mange forskellige objektmodeller, inklusive DOM , XOM , DOM4J og JDOM.

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

String expression = "/tutorials/tutorial";
XPath path = new DOMXPath(expression);
List result = path.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 til din ansøgning, kan du arbejde med enhver af dem, eller du skal muligvis vælge mellem effektivitet og enkelhed.

Du kan finde de fulde arbejdseksempler for denne artikel i vores git-lager her.


Java tag