XML kezelés Javában

Kategória: Java külső könyvtárak.

Először olvassuk el a Szabványok oldal megfelelő szakaszát. A Javából való kezelést nagyrészt belső könyvtárakkal is meg tudjuk oldani, de hogy ne szakadjon ketté, meg logikailag is ide kívánkozik, együtt tárgyaljuk.

Igen tekintélyes mennyiségű a Java XML támogatását leíró szakirodalom; néhány közülük:

DOM

Az XML-nek egy jól definiált, logikus, egyértelmű fa struktúra felépítése van, amit DOM-nak (Document Object Model) hívunk. Ezt a struktúrát fel tudjuk építeni a memóriában is, amit megnézünk ebben a szakaszban.

Példaként hozzuk létre az alábbi fájlt, example.xml néven:

<?xml version="1.0"?>
<persons>
    <person id="1">
        <name>Sanyi</name>
        <age>34</age>
        <city>Budapest</city>
    </person>
    <person id="2">
        <name>Kata</name>
        <city>Budapest</city>
    </person>
    <person id="3">
        <name>Pista</name>
        <age>46</age>
        <city>Szeged</city>
    </person>
</persons>

Először elemezni (angolul parse) kell a dokumentumot, majd különféle bejárásokat tudunk végrehajtani: egy elem attribútumait vagy gyerekeit lekérdezni, tömbök esetén közvetlenül címezni, első gyerek → következő testvér jellegű lineáris bejárást végrehajtani stb. Az alábbi példa bemutat ezek közül pár lehetőséget. Ennek a leírásnak nem célja a DOM bejárási módozatok részletes bemutatása; szükség esetén a lent megadott hivatkozásokat olvassuk el.

import java.io.File;
import java.io.IOException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

public class DomExample {
    public static void main(String[] args) {
        try {
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            Document document = documentBuilder.parse(new File("example.xml"));
            document.getDocumentElement().normalize();

            Element rootElement = document.getDocumentElement();
            System.out.println("Root element: " + rootElement.getNodeName());
            NodeList childNodes = rootElement.getChildNodes();
            for (int i = 0; i < childNodes.getLength(); i++) {
                Node node = childNodes.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    Element element = (Element)node;
                    String id = element.getAttribute("id");
                    System.out.println("id: " + id);

                    Node actualNode = element.getFirstChild();
                    while (actualNode != null) {
                        if (actualNode.getNodeType() == Node.ELEMENT_NODE) {
                            Element actualElement = (Element)actualNode;
                            System.out.println("  " + actualElement.getNodeName() + ": " + actualElement.getTextContent());
                        }
                        actualNode = actualNode.getNextSibling();
                    }
                    System.out.println();
                }
            }
        } catch (ParserConfigurationException | SAXException | IOException e) {
            e.printStackTrace();
        }
    }
}

A DOM feldolgozással kapcsolatos néhány oldal, példaprogramokkal:

XPath

A bejárás kissé nehézkes. A legtöbb esetben konkrét információt szeretnénk kigyűjteni. Az XPath szabványban lefektetett módszerrel egész bonyolult lekérdezéseket is végre tudunk hajtani. Az alábbi példában azoknak az embereknek a neveit kérdezzük le, akik Budapesten laknak. Az XPath kifejezés ez: /persons/person[city='Budapest']/name/text().

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class XpathExample {
    public static void main(String[] args) {
        try {
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            Document document = documentBuilder.parse(new File("example.xml"));

            XPathFactory xpathfactory = XPathFactory.newInstance();
            XPath xpath = xpathfactory.newXPath();
            XPathExpression expr = xpath.compile("/persons/person[city='Budapest']/name/text()");
            Object result = expr.evaluate(document, XPathConstants.NODESET);
            NodeList nodes = (NodeList) result;
            for (int i = 0; i < nodes.getLength(); i++) {
                System.out.println(nodes.item(i).getNodeValue());
            }
        } catch (ParserConfigurationException | SAXException | IOException | XPathExpressionException e) {
            e.printStackTrace();
        }

    }
}

További források az XPath használatára Java-ban:

SAX

A DOM felépítése a memóriában nagyobb XML fájlok esetén rendkívül erőforrás igényes (és most ne a mai számítógépekre gondoljunk elsősorban, hanem azokra, amelyek az XML fénykorában voltak tipikusak), ráadásul ez gyakran felesleges is. Ha az XML struktúrája nem túl bonyolult, viszont túl nagy (a fenti példát vehetjük alapul, de tegyük fel, hogy százmillió ember adatai vannak benne), akkor a DOM helyett használhatjuk a SAX-ot, ami a Simple API for XML rövidítése. Ez a dokumentum elemzés (parse) során minden egyes elemnél általunk megvalósított függvényt hív. Angolul az ilyen megoldást úgy hívjuk, hogy callback. A következő függvényeket kell megvalósítanunk:

  • startElement()): mindegyik XML elem elején hívódik.
  • characters(): két tag közötti szövegre hívódik.
  • endElement(): az XML elemek végén hívódik.

Lássunk egy példát!

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

class SaxHandler extends DefaultHandler {
    private int indent = 0;

    private String formatAttributes(Attributes attributes) {
        int attrLength = attributes.getLength();
        if (attrLength == 0) {
            return "";
        }
        StringBuilder sb = new StringBuilder(", {");
        for (int i = 0; i < attrLength; i++) {
            sb.append(attributes.getLocalName(i) + ":" + attributes.getValue(i));
            if (i < attrLength - 1) {
                sb.append(", ");
            }
        }
        sb.append("}");
        return sb.toString();
    }

    private void indent() {
        for (int i = 0; i < indent; i++) {
            System.out.print("  ");
        }
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) {
        indent++;
        indent();
        System.out.println(qName + formatAttributes(attributes) + " begin");
    }

    @Override
    public void endElement(String uri, String localName, String qName) {
        indent();
        indent--;
        System.out.println(qName + " end");
    }

    @Override
    public void characters(char ch[], int start, int length) {
        String chars = new String(ch, start, length).trim();
        if (!chars.isEmpty()) {
            indent++;
            indent();
            indent--;
            System.out.println(chars);
        }
    }
}

public class SaxExample {
    public static void main(String[] args) {
        try {
            SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
            SAXParser saxParser = saxParserFactory.newSAXParser();
            SaxHandler handler = new SaxHandler();
            saxParser.parse(new File("example.xml"), handler);
        } catch (ParserConfigurationException | SAXException | IOException e) {
            e.printStackTrace();
        }
    }
}

StAX

A StAX a Streaming API for XML processing rövidítése. Ez is része a standard Java könyvtáraknak, így a használatához nem kell importálni semmit. A SAX PUSH modell (tehát az elemző hívja a kezelő függvényeit, ahogy fent láthattuk), míg a StAX PULL modell (tehát annak ellenére, hogy a SAX-hoz hasonlóan a bejárás lineáris, itt az aktív fél a kezelő, ez hívja az elemző függvényeit, a DOM-hoz hasonlóan), így ebben ötvöződnek a DOM és a SAX előnyei.

Lássuk ezt egy példán keresztül; valósítsuk meg a fenti SAX megoldást StAX segítségével:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Iterator;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

public class StaxExample {
    private static int indentLevel = 0;

    private static void indent() {
        for (int i = 0; i < indentLevel; i++) {
            System.out.print("  ");
        }
    }

    public static void main(String[] args) {
        try {
            XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
            XMLEventReader reader = xmlInputFactory.createXMLEventReader(new FileInputStream("example.xml"));
            while (reader.hasNext()) {
                XMLEvent nextEvent = reader.nextEvent();
                if (nextEvent.isStartElement()) {
                    StartElement startElement = nextEvent.asStartElement();
                    indent();
                    indentLevel++;
                    System.out.println("Start element: " + startElement.getName().getLocalPart());
                    Iterator<Attribute> attributesIterator = startElement.getAttributes();
                    while (attributesIterator.hasNext()) {
                        Attribute attribute = attributesIterator.next();
                        indent();
                        System.out.println("Attribute " + attribute.getName().getLocalPart() + ": " + attribute.getValue());
                    }
                }
                if (nextEvent.isEndElement()) {
                    EndElement endElement = nextEvent.asEndElement();
                    indentLevel--;
                    indent();
                    System.out.println("End element: " + endElement.getName().getLocalPart());
                }
            }
        } catch (FileNotFoundException | XMLStreamException e) {
            e.printStackTrace();
        }

    }
}

További dokumentáció a témával kapcsolatban:

DTD validáció

Az XML-nek önmagában szigorú felépítése van, aminek a felépítését tovább specifikálhatjuk. Egy ilyen lehetőség a DTD (Document Type Definition), amit beletehetünk magába az XML fájlba, vagy akár külön fájlba is. Ez utóbbira lássunk egy példát! Módosítsuk az example.xml fájlt az alábbi módon:

<?xml version="1.0"?>
<!DOCTYPE persons SYSTEM "example.dtd">
<persons>
...

Valósítsuk meg a hivatkozott example.dtd fájlt is:

<!ELEMENT persons (person*)>
<!ELEMENT person (name,age?,city)>
<!ATTLIST person id CDATA "0">
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT city (#PCDATA)>

Ezzel megadtuk az XML felépítését: a gyökér elem a persons, ami akárhány person elemet tartalmazhat. A person felépítése: id attribútum, name elem, age opcionális elem és city elem. A domFactory.setValidating(true) függvényhívással megadhatjuk, hogy az elemzés során ellenőrizze-e az XML felépítésének helyességét:

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class DtdValidation {
    public static void main(String[] args) {
        try {
            DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
            domFactory.setValidating(true);
            DocumentBuilder documentBuilder = domFactory.newDocumentBuilder();
            documentBuilder.setErrorHandler(new ErrorHandler() {
                @Override
                public void warning(SAXParseException exception) throws SAXException {
                    System.out.println("Warning: " + exception);
                }

                @Override
                public void error(SAXParseException exception) throws SAXException {
                    System.out.println("Error: " + exception);
                }

                @Override
                public void fatalError(SAXParseException exception) throws SAXException {
                    System.out.println("Fatal error: " + exception);
                }
            });
            documentBuilder.parse("example.xml");
            System.out.println("DTD validation finished.");
        } catch (SAXException | IOException | ParserConfigurationException e) {
            e.printStackTrace();
        }
    }
}

Ez a példa úgy van felépítve, hogy működjön. De játsszunk el vele kicsit, pl. ideiglenesen töröljük ki az age utáni kérdőjelet (az jelzi ugyanis, hogy az az elem opcionális). Ez esetben - mivel Kata esetén nem adtuk meg - hibát fog jelezni. Ugyanakkor ellenőrzés nélkül rendben lefutnának a műveletek.

XSD validáció

A DTD mellett létezik egy másik, valójában jóval elterjedtebb XML validációs módszer is: ez az XSD (XML Schema Definition). EZ magát az XML-t definiálja, és az XSD felépítése önmagában XML. A fenti példa XSD definíciója például az alábbi lehet:

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="persons">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="person" maxOccurs="unbounded">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="name" type="xs:string"/>
            <xs:element name="age" type="xs:positiveInteger" minOccurs="0"/>
            <xs:element name="city" type="xs:string"/>
          </xs:sequence>
          <xs:attribute name="id" type="xs:positiveInteger" use="required"/>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
</xs:element>

</xs:schema>

Az alábbi Java program végrehajtja az XSD szerinti validálást. Célszerű (bár nem kötelező) előbb kivenni az XML-ből a DTD validációt.

import java.io.File;
import java.io.IOException;
import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.xml.sax.SAXException;

public class XsdValidation {
    public static void main(String[] args) {
        try {
            Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(new File("example.xsd"));
            schema.newValidator().validate(new StreamSource(new File("example.xml")));
            System.out.println("XSD validation passed.");
        } catch (SAXException | IOException e) {
            e.printStackTrace();
        }
    }
}

További források a témával kapcsolatban:

JAXB

A Java-ban tipikusan osztályokkal és objektumokkal dolgozunk. Létezik egy többé-kevésbé egyértelmű megfeleltetés a Java objektumorientált világa és az XML hierarchikus világa között. A fenti példában az egész XML megfelel egy személyekből álló listának, a személynek meg van azonosítója, neve, életkora és lakóhelye. A Java osztály persze nem tesz különbséget az XML attribútum és XML elem között, és van még néhány kisebb eltérés, de azért el tudjuk képzelni a konverziót a kettő között. A fenti módszerekkel viszont igen nehézkes ez a művelet, sok kódot kell hozzá írni, és problémát jelent a változtatások nyomkövetése is.

A JAXB ezt a problémát orvosolja: megteremti a kapcsolatot a két rendszer között. Ehhez megfelelően annotált osztályokat kell létrehoznunk, és ezután viszonylag kevés kóddal meg tudjuk oldani a konverziót. Két fogalommal ismerkedjünk meg:

  • Mashalling: ez az a folyamat, amikor objektumból XML-t hozunk létre.
  • Unmarshalling: az ellentétes folyamat, tehát amikor XML-ből hozzuk létre az objektumot.

Lássuk mindezt egy példán keresztül! Hozzuk létre a személy listát kezelő osztályt (Persons.java):

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Persons {
    private List<Person> persons;

    public Persons() {}

    public Persons(List<Person> persons) {
        super();
        this.persons = persons;
    }

    public List<Person> getPersons() {
        return persons;
    }

    @XmlElement(name = "person")
    public void setPersons(List<Person> persons) {
        this.persons = persons;
    }
}

Az @XmlRootElement és az @XmlElement annotációk elegendőek a feladat megoldásához. A személyt leíró osztály az alábbi (Person.java):

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlType(propOrder = {"name", "age", "city"})
public class Person {
    private Integer id;
    private String name;
    private Integer age;
    private String city;

    public Person() {}

    public Person(Integer id, String name, Integer age, String city) {
        super();
        this.id = id;
        this.name = name;
        this.age = age;
        this.city = city;
    }

    @XmlAttribute
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    @XmlElement
    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    @XmlElement
    public void setAge(Integer age) {
        this.age = age;
    }

    public String getCity() {
        return city;
    }

    @XmlElement
    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", age=" + age + ", city=" + city + "]";
    }
}

Végül lássuk a marshalling és unmarshalling kódját:

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.*;

public class JaxbExample {
    public static void main(String[] args) {
        List<Person> persons = new ArrayList<Person>();
        persons.add(new Person(1, "Sanyi", 34, "Budapest"));
        persons.add(new Person(2, "Kata", null, "Budapest"));
        persons.add(new Person(3, "Pista", 46, "Szeged"));
        objectToXml(new Persons(persons));
        System.out.println();

        Persons generatedObject = xmlToObject(new File("example.xml"));
        System.out.println("Persons:");
        for (Person person: generatedObject.getPersons()) {
            System.out.println(person);
        }
    }

    private static void objectToXml(Persons persons) {
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(Persons.class);
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            jaxbMarshaller.marshal(persons, System.out);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }

    private static Persons xmlToObject(File file) {
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(Persons.class);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            Persons persons = (Persons)jaxbUnmarshaller.unmarshal(file);
            return persons;
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return null;
    }
}

Látható, hogy igen rövid kódrészlet elegendő a feldolgozás mindkét irányához.

Fontos megjegyzés: a JAXB csak a 8-as verzióig volt támogatott. A 9-es és 10-es verziókban elavulttá nyilvánították, és 11-esből pedig ki is vették. (Ez azt is jelenti, hogy ha 8-as módban használjuk a 11-es Java-t, akkor is fordítási hibára fut.) A következő külső függőségekkel tudjuk működésre bírni (https://stackoverflow.com/questions/52502189/java-11-package-javax-xml-bind-does-not-exist):

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-core</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.3.0</version>
</dependency>

További források:

JAXB2

A fenti példának van még egy problémája: még egy ilyen egyszerű esetben is túl sokat kellett gépelni az XML struktúrákat tároló osztályok megvalósításánál. Valójában ez is egy igen jól automatizálható dolog, különösen akkor, ha rendelkezésünkre áll az XML sémát definiáló XSD fájl. A JAXB2 egy olyan Maven beépülő, amely fordítási időben legenerálja az XSD-ből a Java fájlokat. Lássunk erre is egy példát! Hozzunk létre egy Maven projektet, ahol a pom.xml a következőképpen néz ki:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>hu.faragocsaba</groupId>
    <artifactId>jaxb2example</artifactId>
    <version>1.0</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <build>
        <plugins>    
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>jaxb2-maven-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <id>xjc</id>
                        <goals>
                            <goal>xjc</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <sources>
                        <source>src/main/resources/example.xsd</source>
                    </sources>
                    <outputDirectory>${basedir}/src/main/java</outputDirectory>
                    <clearOutputDir>false</clearOutputDir>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Futtassuk le, pl. mvn clean install. Eredményül az src/main/java/generated könyvtárban: ObjectFactory.java és Persons.java; ez utóbbi tartalmazza a Person osztályt is. Ezt a fenihez hasonló módon használhatjuk:

package jaxb2example;

import java.io.File;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import generated.Persons;
import generated.Persons.Person;

public class Jaxb2Example {
    public static void main(String[] args) {
        Persons persons = new Persons();

        Person sanyi = new Person();
        sanyi.setId(BigInteger.valueOf(1));
        sanyi.setName("Sanyi");
        sanyi.setAge(BigInteger.valueOf(34));
        sanyi.setCity("Budapest");
        persons.getPerson().add(sanyi);

        Person kata = new Person();
        kata.setId(BigInteger.valueOf(2));
        kata.setName("Kata");
        kata.setCity("Budapest");
        persons.getPerson().add(kata);

        Person pista = new Person();
        pista.setId(BigInteger.valueOf(3));
        pista.setName("Pista");
        pista.setAge(BigInteger.valueOf(46));
        pista.setCity("Szeged");
        persons.getPerson().add(pista);

        objectToXml(persons);
        System.out.println();

        Persons generatedObject = xmlToObject(new File("example.xml"));
        System.out.println("Persons:");
        for (Person person: generatedObject.getPerson()) {
            System.out.println("Person [id=" + person.getId()
                + ", name=" + person.getName()
                + ", age=" + person.getAge()
                + ", city=" + person.getCity() + "]");
        }
    }

    private static void objectToXml(Persons persons) {
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(Persons.class);
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            jaxbMarshaller.marshal(persons, System.out);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }

    private static Persons xmlToObject(File file) {
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(Persons.class);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            Persons persons = (Persons)jaxbUnmarshaller.unmarshal(file);
            return persons;
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return null;
    }
}

Az előkészületek kicsit hosszabbak lettek, mivel a számunkra kényelmes konstruktort nem generálta le. (Egészen biztosan lehet ilyet is csinálni megfelelő konfigurációval, de ennek nem jártam részletesebben utána.)

További lehetőségek

Ennek a területnek (is) csak a felszínét karcoltuk. A bemutatott könyvtáraknak további lehetőségei vannak, ill. vannak más könyvtárak, amelyeknek esetleg lehetne olyan tulajdonságaik, amelyek miatt megfontolandó, hogy valós üzleti környezetben inkább azt használjuk. A teljesség igénye nélkül felsorolok néhány lényeges dokumentumot:

További XML feldolgozók:

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License