JAXB и STAX, получая ноль, когда элемент в дереве имеет атрибут - PullRequest
0 голосов
/ 17 октября 2018

У меня проблема с unmarshaling xml.Когда я отменяю маршализацию XML, который не имеет никаких атрибутов, он работает просто отлично, но когда я пытаюсь демаршировать XML, который имеет атрибут в любом элементе, я получаю только нулевые значения.

Вот мой код:

<Document xmlns="sd">
<CstmrCdtTrfInitn>
    <GrpHdr>
        <NbOfTxs>2</NbOfTxs>
        <CtrlSum>100</CtrlSum>
        <blabla>bla</blabla>
    </GrpHdr>
    <PmtInf>
        <NbOfTxs>2</NbOfTxs>
        <CtrlSum>100</CtrlSum>
        <blabla>bla</blabla>
    </PmtInf>
</CstmrCdtTrfInitn>
</Document>

XML-схема:

package XMLElement;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "GrpHdr")
@XmlAccessorType(XmlAccessType.FIELD)
public class GrpHdr {   

@XmlElement(name = "MsgId")
private String msgId;
@XmlElement(name = "CreDtTm")
private String creDtTm;
@XmlElement(name = "NbOfTxs")
private String nbOfTxs;
@XmlElement(name = "CtrlSum")
private String ctrlSum;
@XmlElement(name = "InitgPty")
private String initgPty;

// MsgId
public String getMsgId() {
    return msgId;
}

public void setMsgId(String string_msgId) {
    msgId = string_msgId;
}


// CreDtTm
public String getCreDtTm() {
    return creDtTm;
}

public void setCreDtTm(String string_creDtTm) {
    creDtTm = string_creDtTm;
}


// NbOfTxs
public String getNbOfTxs() {
    return nbOfTxs;
}

public void setNbOfTxs(String string_nbOfTxs) {
    nbOfTxs = string_nbOfTxs;
}


// CtrlSum
public String getCtrlSum() {
    return ctrlSum;
}

public void setCtrlSum(String string_ctrlSum) {
    ctrlSum = string_ctrlSum;
}


// InitgPty
public String getInitgPty() {
    return initgPty;
}

public void setInitgPty(String string_initgPty) {
    initgPty = string_initgPty;
}




}

И Main.java

package application;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.stream.StreamSource;

import XMLElement.CstmrCdtTrfInitn;
import XMLElement.Document;
import XMLElement.GrpHdr;
import XMLElement.PmtInf;

public class Main {

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

        XMLInputFactory xif2 = XMLInputFactory.newFactory();
        StreamSource xml2 = new StreamSource("D:\\test2.xml");
        XMLStreamReader xsr2 = xif2.createXMLStreamReader(xml2);
        xsr2.nextTag();
        while(xsr2.hasNext()) {
            if(xsr2.isStartElement() && 
xsr2.getLocalName().equals("GrpHdr")) {
                break;
            }
            xsr2.next();
        }

        JAXBContext jc2 = JAXBContext.newInstance(GrpHdr.class);
        Unmarshaller unmarshaller2 = jc2.createUnmarshaller();
        JAXBElement<GrpHdr> jb2 = unmarshaller2.unmarshal(xsr2, 
 GrpHdr.class);
        xsr2.close();


        GrpHdr grpHdr = jb2.getValue();
        System.out.println(grpHdr.getNbOfTxs());
        System.out.println(grpHdr.getCtrlSum());

        }
}

Когда я удаляю xmlns="sd", я получаю результат без проблем, нов противном случае я получаю только ноль.Любые предложения о том, что я делаю не так?

1 Ответ

0 голосов
/ 17 октября 2018

Обратите внимание, что xmlns обозначает пространство имен XML.Таким образом, если у вас есть пространство имен в вашем XML-документе, оно будет связывать все теги XML-документа с этим пространством имен, поэтому очевидно, что XML unmarshalling не будет работать, потому что ваш тег будет говорить sd:XYZи JAXB будет проверять только на XYZ.

Вы должны также объявить пространство имен в своем классе отображения XML, чтобы эта работа работала с пространством имен (или удалить пространство имен, если оно вам не нужно).Вы можете добавить аннотацию XmlSchema в свой класс document , чтобы он работал с атрибутом xmlns.

@XmlSchema(
    namespace = "http://www.example.com/namespaceURI",
    elementFormDefault = XmlNsForm.QUALIFIED,
    xmlns = {
        @XmlNs(prefix="sd", namespaceURI="http://www.example.com/namespaceURI")
    }
)
...