Вопрос:
Я использую JAXB для unsmarshal ответа XML из запроса SOAP, и я получаю следующую ошибку:
unexpected element (uri:»http://www.portalfiscal.inf.br/nfe», local:»NFe»). Expected elements are <{}protNFe>,<{}NFe>
Это важная часть полученного XML:
[…]
<XmlNFCe> <nfeProc xmlns=»http://www.portalfiscal.inf.br/nfe» versao=»3.10″> <NFe> <infNFe versao=»3.10″ Id=»NFe43140215402636000137651040000000161893466508″> <ide>… </NFe> <protNFe>…
[…]
Этот класс представляет собой корневой тег. Это целевой класс, который я использую для unmarshall:
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name=»XmlNFCe», propOrder={ «nfeProc» }) @XmlRootElement(name=»XmlNFCe», namespace=»») public class XmlNfce { @XmlElement(name=»nfeProc», namespace=»http://www.portalfiscal.inf.br/nfe») private NFeProc nfeProc; public NFeProc getNfeProc() { return nfeProc; } public void setNfeProc(NFeProc nfeProc) { this.nfeProc = nfeProc; } }
И эти три класса являются дочерними тегами:
Первый класс:
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name=»nfeProc», propOrder={ «NFe», «protNFe» }) @XmlRootElement(name=»nfeProc», namespace=»http://www.portalfiscal.inf.br/nfe») public class NFeProc { @XmlElement(name=»NFe», namespace=»», type=NFe.class) private NFe NFe; @XmlElement(name=»protNFe», namespace=»», type=ProtNFe.class) private ProtNFe protNFe; public NFe getNFe() { return NFe; } public void setNFe(NFe nFe) { NFe = nFe; } public ProtNFe getProtNFe() { return protNFe; } public void setProtNFe(ProtNFe protNFe) { this.protNFe = protNFe; } }
Второй класс:
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name=»NFe», propOrder={ «infNFe», «Signature» }) @XmlRootElement(name=»NFe», namespace=»») public class NFe { @XmlElement(name=»infNfe») private InfNfe infNFe; @XmlElement(name=»Signature») private Signature Signature; public InfNfe getInfNFe() { return infNFe; } public void setInfNFe(InfNfe infNFe) { this.infNFe = infNFe; } public Signature getSignature() { return Signature; } public void setSignature(Signature signature) { this.Signature = signature; } }
Класс третий:
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name=»protNFe», propOrder={ «infProt» }) @XmlRootElement(name=»protNFe», namespace=»») public class ProtNFe { @XmlElement(name=»infProt») private InfProt infProt; public InfProt getInfProt() { return infProt; } public void setInfProt(InfProt infProt) { this.infProt = infProt; } } Лучший ответ:
Если я не помню неправильно, элементы XML наследуют пространство имен своего родителя, если они не объявляют сами.
Итак, в
<nfeProc xmlns=»http://www.portalfiscal.inf.br/nfe» versao=»3.10″> <NFe> <infNFe versao=»3.10″ Id=»NFe43140215402636000137651040000000161893466508″> <ide>… </NFe>
элемент <NFe> имеет такое же пространство имен, что и <nfeProc>, т.е. . Однако в ваших Java-классах они отображаются в пространство имен, состоящее из пустой строки «».
@XmlElement(name=»NFe», namespace=»», type=NFe.class) private NFe NFe; @XmlElement(name=»protNFe», namespace=»», type=ProtNFe.class) private ProtNFe protNFe;
Таким образом, unmarshaller находит элемент <NFe> с пространством имен , но это не то, что он ожидает, поскольку ошибка говорит
unexpected element (uri:»http://www.portalfiscal.inf.br/nfe», local:»NFe»). Expected elements are <{}protNFe>,<{}NFe>
Просто исправьте свои объявления пространства имен, где это необходимо.
Ответ №1
Похоже, что ваш XML, из которого вы создали jaxb-классы, неверен.
В вас XML nfeProc – это корневой элемент, для которого определено пространство имен, а дочерние элементы NFE и protNFe не имеют определенного пространства имен.
для решения этой проблемы создайте отдельное пространство имен для