You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JAXB反序列化异常:意外元素(uri:"", local:"network")求助

JAXB反序列化XML到Network对象时抛出UnmarshalException异常的解决方法

问题描述

使用JAXB将XML文件反序列化为Network对象时,抛出javax.xml.bind.UnmarshalException异常,提示:

unexpected element (uri:"", local:"network"). Expected elements are <{urn:com.myproject.server.ws.dto.cfg}FullSiteDiversity>,<{urn:com.myproject.server.ws.dto.cfg}Network>,<{urn:com.myproject.server.ws.dto.cfg}SupportedFeatures>

POJO代码

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Network", namespace = "urn:com.myproject.server.ws.dto.cfg")
@XmlType(name = "Network", namespace = "urn:com.myproject.server.ws.dto.cfg")
public class Network {
    @NotNull
    @Valid
    private NetworkSupportedFeaturesSection supportedFeatures;

    @Valid
    private NetworkFullSiteDiversitySection fullSiteDiversity;

    public NetworkSupportedFeaturesSection getSupportedFeatures() {
        return supportedFeatures;
    }

    public void setSupportedFeatures(NetworkSupportedFeaturesSection supportedFeatures) {
        this.supportedFeatures = supportedFeatures;
    }

    public NetworkFullSiteDiversitySection getFullSiteDiversity() {
        return fullSiteDiversity;
    }

    public void setFullSiteDiversity(NetworkFullSiteDiversitySection fullSiteDiversity) {
        this.fullSiteDiversity = fullSiteDiversity;
    }
}

XML内容

<network>
    <supportedFeatures>
        <nmsDiversity>ENABLE</nmsDiversity>
        <fullSiteDiversity>ENABLE</fullSiteDiversity>
    </supportedFeatures>
    <fullSiteDiversity>
        <activeDc>DC2</activeDc>
        <active1NGw>My_Teleport_5_GW_Main</active1NGw>
    </fullSiteDiversity>
</network>

单元测试代码

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

@Test
public void should_throw_exception_with_error_message_when_execute_operation_with_corrupted_parameter2() throws IOException {
    URL url = getClass().getResource(PATH_TO_FULL_SITE_DIVERSITY_RESOURCES + "/network_node.xml");
    Optional<Network> network = convertXMLToObject(url);
}

private static Optional<Network> convertXMLToObject(URL url) {
    try {
        JAXBContext context = JAXBContext.newInstance(Network.class);
        Unmarshaller un = context.createUnmarshaller();
        return Optional.of((Network) un.unmarshal(url)); // 报错位置
    } catch (JAXBException e) {
        LOGGER.error(e.getMessage(), e);
    }
    return Optional.empty();
}

完整报错堆栈

2023-05-30 15:11:57.705 ERROR [NetworkWebServiceTest:main] unexpected element (uri:"", local:"network"). Expected elements are <{urn:com.myproject.server.ws.dto.cfg}FullSiteDiversity>,<{urn:com.myproject.server.ws.dto.cfg}Network>,<{urn:com.myproject.server.ws.dto.cfg}SupportedFeatures>
javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"network"). Expected elements are <{urn:com.myproject.server.ws.dto.cfg}FullSiteDiversity>,<{urn:com.myproject.server.ws.dto.cfg}Network>,<{urn:com.myproject.server.ws.dto.cfg}SupportedFeatures>
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:712) ~[jaxb-runtime-2.3.5.jar:2.3.5]
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:232) ~[jaxb-runtime-2.3.5.jar:2.3.5]
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:227) ~[jaxb-runtime-2.3.5.jar:2.3.5]
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:94) ~[jaxb-runtime-2.3.5.jar:2.3.5]
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1117) ~[jaxb-runtime-2.3.5.jar:2.3.5]
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:542) ~[jaxb-runtime-2.3.5.jar:2.3.5]
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:524) ~[jaxb-runtime-2.3.5.jar:2.3.5]
    at com.sun.xml.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:137) ~[jaxb-runtime-2.3.5.jar:2.3.5]
    at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source) ~[xercesImpl-2.12.2.jar:?]
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source) ~[xercesImpl-2.12.2.jar:2.12.2]
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source) ~[xercesImpl-2.12.2.jar:2.12.2]
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source) ~[xercesImpl-2.12.2.jar:2.12.2]
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) ~[xercesImpl-2.12.2.jar:2.12.2]
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) ~[xercesImpl-2.12.2.jar:?]
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) ~[xercesImpl-2.12.2.jar:?]
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source) ~[xercesImpl-2.12.2.jar:?]
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source) ~[xercesImpl-2.12.2.jar:?]
    at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source) ~[xercesImpl-2.12.2.jar:?]
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:228) ~[jaxb-runtime-2.3.5.jar:2.3.5]
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:199) ~[jaxb-runtime-2.3.5.jar:2.3.5]
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157) ~[?:1.8.0_342]
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162) ~[?:1.8.0_342]
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171) ~[?:1.8.0_342]
    at com.myproject.integrationtest.server.ws.NetworkWebServiceTest.convertXMLToObject(NetworkWebServiceTest.java:106) ~[test-classes/:?]
    at com.myproject.integrationtest.server.ws.NetworkWebServiceTest.should_throw_exception_with_error_message_when_execute_operation_with_corrupted_parameter2(NetworkWebServiceTest.java:98) ~[test-classes/:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_342]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_342]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_342]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_342]
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:61) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413) ~[junit-4.13.2.jar:4.13.2]
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137) ~[junit-4.13.2.jar:4.13.2]
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69) ~[junit-rt.jar:?]
    at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) ~[junit-rt.jar:?]
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) ~[idea_rt.jar:?]
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) ~[junit-rt.jar:?]
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232) ~[junit-rt.jar:?]
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55) ~[junit-rt.jar:?]

解决方法

方案一:修改XML匹配POJO配置

JAXB期望带命名空间urn:com.myproject.server.ws.dto.cfg且首字母大写的<Network>元素,当前XML根元素是无命名空间的小写<network>。修改后的XML如下:

<Network xmlns="urn:com.myproject.server.ws.dto.cfg">
    <supportedFeatures>
        <nmsDiversity>ENABLE</nmsDiversity>
        <fullSiteDiversity>ENABLE</fullSiteDiversity>
    </supportedFeatures>
    <fullSiteDiversity>
        <activeDc>DC2</activeDc>
        <active1NGw>My_Teleport_5_GW_Main</active1NGw>
    </fullSiteDiversity>
</Network>

子元素会自动继承根元素的命名空间,无需单独声明。

方案二:修改POJO适配现有XML

如果无法修改XML,可调整POJO的JAXB注解,去掉命名空间并将元素名改为小写:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "network")
@XmlType(name = "network")
public class Network {
    @NotNull
    @Valid
    private NetworkSupportedFeaturesSection supportedFeatures;

    @Valid
    private NetworkFullSiteDiversitySection fullSiteDiversity;

    // getter和setter方法保持不变
}

同时需确保关联的POJO(如NetworkSupportedFeaturesSection)也去掉命名空间,并将对应元素名改为小写(比如@XmlRootElement(name = "supportedFeatures"))。

方案三:忽略命名空间差异(临时兼容)

如需临时兼容无命名空间的XML,可通过设置Unmarshaller属性忽略命名空间,但可能引发其他兼容性问题,仅作临时方案:

private static Optional<Network> convertXMLToObject(URL url) {
    try {
        JAXBContext context = JAXBContext.newInstance(Network.class);
        Unmarshaller un = context.createUnmarshaller();
        // 忽略命名空间
        un.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapper() {
            @Override
            public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
                return "";
            }
        });
        return Optional.of((Network) un.unmarshal(url));
    } catch (JAXBException e) {
        LOGGER.error(e.getMessage(), e);
    }
    return Optional.empty();
}

内容的提问来源于stack exchange,提问作者Alexei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 13:57:01