@MaxLich
java developer

Почему не получается распарсить xml?

Здравствуйте. В мою программу приходит строка в виде xml-документа. Мне нужно её парсить (превращать в нужные объекты). Использую базовый JAXB. Расставил все комментарии, написал нужный код, но почему-то он не парсит нужный объект. Пример XML:
xml
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<documentrequest type="staff" mode_display="employ_and_dismiss" subdiv="">
    <staff>
        <staffnode last_name="Бердников" first_name="Дмитрий" middle_name="" id_internal="1333771" id_external=""
                   tabel_id="0000000000" date_begin="01.01.1980" date_action="01.01.1980" id_subdiv_external=""
                   id_appoint_external="{53B582F1-ECEB-4581-BC06-19C24228B11F}"
                   id_graphwork_external="{3A1E523D-3936-4E20-A08A-D07ABAE5BC20}" id_subdiv_internal="1333419"
                   id_appoint_internal="1333397" id_graphwork_internal="1333495" date_dismiss="" path_photo="">
            <identifiers/>
        </staffnode>
        <staffnode last_name="Богаткина" first_name="Светлана" middle_name="Владимировна" id_internal="1333772"
                   id_external="" tabel_id="0000000000" date_begin="01.01.1980" date_action="01.01.1980"
                   id_subdiv_external="" id_appoint_external="{53B582F1-ECEB-4581-BC06-19C24228B11F}"
                   id_graphwork_external="{3A1E523D-3936-4E20-A08A-D07ABAE5BC20}" id_subdiv_internal="1333411"
                   id_appoint_internal="1333397" id_graphwork_internal="1333495" date_dismiss="" path_photo="">
              <identifiers>
                <identifier type_identifier="family_number" id_card="7466" identifier="9236095"
                            identifier_transformed="9236095" date_begin_action="23.08.2016" date_end_action="01.01.3015"
                            prohibit="false"/>
            </identifiers>

        </staffnode>
        <staffnode last_name="Борзунова" first_name="Лилия" middle_name="Владимировна" id_internal="1333773"
                   id_external="" tabel_id="0000000000" date_begin="01.01.1980" date_action="01.01.1980"
                   id_subdiv_external="" id_appoint_external="{14FBA985-0576-485A-8ED8-D6E81DC92BFC}"
                   id_graphwork_external="{3A1E523D-3936-4E20-A08A-D07ABAE5BC20}" id_subdiv_internal="1333429"
                   id_appoint_internal="1333389" id_graphwork_internal="1333495" date_dismiss="" path_photo="">
            <identifiers/>
        </staffnode>
        <staffnode last_name="Бут" first_name="Наталья" middle_name="Николаевна" id_internal="1333775" id_external=""
                   tabel_id="0000000000" date_begin="01.01.1980" date_action="01.01.1980" id_subdiv_external=""
                   id_appoint_external="{53B582F1-ECEB-4581-BC06-19C24228B11F}"
                   id_graphwork_external="{3A1E523D-3936-4E20-A08A-D07ABAE5BC20}" id_subdiv_internal="1333409"
                   id_appoint_internal="1333397" id_graphwork_internal="1333495" date_dismiss="" path_photo="">
            <identifiers/>
        </staffnode>
    </staff>
</documentrequest>


Мой код, который занимается парсингом:
code for parsing
//parse the response with the list of employees
    public static List<Employee> parseXmlStaff(String xml) throws JAXBException {
        DocumentRequest documentRequest = (DocumentRequest) parse(xml,
                Employee.class, AccessCard.class,DocumentRequest.class);
        return documentRequest.getStaff();
    }
    private static Object parse(String xml, Class...classToBeBound) throws JAXBException {
        Reader reader = new StringReader(xml);

        JAXBContext context = JAXBContext.newInstance(classToBeBound);
        Unmarshaller unmarshaller = context.createUnmarshaller();

        return unmarshaller.unmarshal(reader);
    }


Классы объектов, которые парсятся:
classes
@XmlRootElement(name = "documentrequest")
public class DocumentRequest {
    private List<Employee> staff;
    //------------- Getters and Setters ----------------------------
    @XmlElement(name = "staffnode")
    @XmlElementWrapper(name = "staff")
    public List<Employee> getStaff() {
        return staff;
    }
    public void setStaff(List<Employee> staff) {
        this.staff = staff;
    }

}


@XmlRootElement(name = "staffnode")
public class Employee {
    private String firstName;
    private String middleName;
    private String lastName;
    private String pathToPhoto;
    private int idInternal;
    private String idExternal;
    private int tabelId;
    private Date dateBegin;
    private Date dateAction;
    private String idSubdivExternal;
    private String idGraphworkExternal;
    private String idAppointExternal;
    private int idSubdivInternal;
    private int idGraphworkInternal;
    private int idAppointInternal;
    private Date dateDismiss;

    private List<AccessCard> accessCards;

    public Employee() {
    }

    public Employee(String firstName, String middleName, String lastName,
                    String pathToPhoto, int idInternal, String idExternal, int tabelId,
                    Date dateBegin, Date dateAction, String idSubdivExternal,
                    String idGraphworkExternal, String idAppointExternal, int idSubdivInternal,
                    int idGraphworkInternal, int idAppointInternal, Date dateDismiss) {
        this.firstName = firstName;
        this.middleName = middleName;
        this.lastName = lastName;
        this.pathToPhoto = pathToPhoto;
        this.idInternal = idInternal;
        this.idExternal = idExternal;
        this.tabelId = tabelId;
        this.dateBegin = dateBegin;
        this.dateAction = dateAction;
        this.idSubdivExternal = idSubdivExternal;
        this.idGraphworkExternal = idGraphworkExternal;
        this.idAppointExternal = idAppointExternal;
        this.idSubdivInternal = idSubdivInternal;
        this.idGraphworkInternal = idGraphworkInternal;
        this.idAppointInternal = idAppointInternal;
        this.dateDismiss = dateDismiss;
    }

    @XmlAttribute(name = "first_name")
    public String getFirstName() {
        return firstName;
    }


    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    @XmlAttribute(name = "middle_name")
    public String getMiddleName() {
        return middleName;
    }

    public void setMiddleName(String middleName) {
        this.middleName = middleName;
    }
//some code: getters and setters

    @XmlAttribute(name = "id_appoint_internal")
    public int getIdAppointInternal() {
        return idAppointInternal;
    }

    public void setIdAppointInternal(int idAppointInternal) {
        this.idAppointInternal = idAppointInternal;
    }

    @XmlAttribute(name = "date_dismiss")
    @XmlJavaTypeAdapter(DateAdapter.class)
    public Date getDateDismiss() {
        return dateDismiss;
    }

    public void setDateDismiss(Date dateDismiss) {
        this.dateDismiss = dateDismiss;
    }

    @XmlElementWrapper(name = "identifiers")
    @XmlElement("identifier")
    public List<AccessCard> getAccessCard() {
        return accessCards;
    }

    public void setAccessCard(List<AccessCard> accessCards) {
        this.accessCards = accessCards;
    }
}

@XmlRootElement(name = "identifier")
public class AccessCard {
    private String TypeIdentifier;
    private int idCard;
    private int identifier;
    private int identifierTransformed;
    private Date dateBegin;
    private Date dateEnd;
    private boolean prohibit;

    @XmlAttribute(name = "type_identifier")
    public String getTypeIdentifier() {
        return TypeIdentifier;
    }

    public void setTypeIdentifier(String typeIdentifier) {
        TypeIdentifier = typeIdentifier;
    }

    @XmlAttribute(name = "id_card")
    public int getIdCard() {
        return idCard;
    }

    public void setIdCard(int idCard) {
        this.idCard = idCard;
    }

    @XmlAttribute(name = "identifier")
    public int getIdentifier() {
        return identifier;
    }

    public void setIdentifier(int identifier) {
        this.identifier = identifier;
    }

//some code
}

Проблема, что он не получает карточки доступа (тег identifier), всё остальное - получает.
  • Вопрос задан
  • 289 просмотров
Решения вопроса 2
@protven
Как делать правильно (имхо).
- написать xsd
- по xsd сгенерить с помощью xjc классы для jaxb (оптимально делать это при сборке, плагином для мейвена/гредла)
- пользоваться этими классами.
Вот пример сгенеренного класса по вашей xml-лине. У меня все работает
https://pastebin.com/JWZJGM8A

Вот main и вывод при запуске
Main.java
import generated.Documentrequest;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.InputStream;

public class Main {


    public static void main(String[] args) throws JAXBException {

        InputStream xml =
                Thread.currentThread().getContextClassLoader().getResourceAsStream("test.xml");

        JAXBContext jaxbContext = JAXBContext.newInstance(Documentrequest.class);

        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

        Documentrequest documentrequest = (Documentrequest) unmarshaller.unmarshal(xml);

        System.out.println(documentrequest.getStaff().getStaffnode().size());


    }
}


Вывод при запуске - 4
Ответ написан
Комментировать
@MaxLich Автор вопроса
java developer
Была ошибка с импортом: импортировал не ту аннотацию (XmlElement). Исправил, но теперь вылетает NPE. Как раз при анмаршаллинге.
Сама ошибка:
стек-трейс эксепшена из консоли
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at com.sun.xml.internal.bind.v2.runtime.reflect.Lister$CollectionLister.addToPack(Lister.java:289)
at com.sun.xml.internal.bind.v2.runtime.reflect.Lister$CollectionLister.addToPack(Lister.java:253)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Scope.add(Scope.java:106)
at com.sun.xml.internal.bind.v2.runtime.property.ArrayERProperty$ReceiverImpl.receive(ArrayERProperty.java:198)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.endElement(UnmarshallingContext.java:597)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.endElement(SAXConnector.java:165)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:609)
at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:183)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:351)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2784)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:841)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:214)
at org.limantrade.model.xml.XmlParser.parse(XmlParser.java:59)
at org.limantrade.model.xml.XmlParser.parseXmlStaff(XmlParser.java:18)
at org.limantrade.model.PercoConnectorMock.getStaffList(PercoConnectorMock.java:42)
at org.limantrade.model.MainModel.loadTableModelEmployees(MainModel.java:68)
at org.limantrade.model.MainModel.loadTableModel(MainModel.java:51)
at org.limantrade.controller.MainController.onRefreshTable(MainController.java:29)
at org.limantrade.view.ViewGUI.fireUpdateTable(ViewGUI.java:163)
at org.limantrade.view.guicomponents.PanelTableWithButton.lambda$addComponents$0(PanelTableWithButton.java:57)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6533)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6298)
at java.awt.Container.processEvent(Container.java:2237)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2295)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4889)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4526)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4467)
at java.awt.Container.dispatchEventImpl(Container.java:2281)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы