javax.xml.bind.UnmarshalException:意外元素(uri:“”,本地:“Group”)

问题描述 投票:0回答:16

从 XML 解组时遇到异常:

    unexpected element (uri:"", local:"Group"). Expected elements are <{}group>

Group
类没有注释,
group.xml
仅包含数据。

    JAXBContext jc = JAXBContext.newInstance(Group.class); 
    Unmarshaller unmarshaller = jc.createUnmarshaller();
    Group group = (User)unmarshaller.unmarshal(new File("group.xml"));

可能是什么原因?

java xml jaxb
16个回答
136
投票

看起来您的 XML 文档的根元素是“Group”而不是“group”。你可以:

  1. 将 XML 上的根元素更改为“group”
  2. 将注释 @XmlRootElement(name="Group") 添加到 Group 类。

52
投票

幸运的是,package-info 类不是必需的。我能够使用 iowatiger08 解决方案解决我的问题。

这是我的修复程序,显示了错误消息,以帮助某些人连接点。

错误信息

javax.xml.bind.UnmarshalException:意外元素 (uri:“http://global.aon.bz/schema/cbs/archive/errorresource/0”, 本地:“错误资源”)。预期的元素是 <{}errorresource>

修复前的代码

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="", propOrder={"error"})
@XmlRootElement(name="errorresource")
public class Errorresource

修复后的代码

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="", propOrder={"error"})
@XmlRootElement(name="errorresource", namespace="http://global.aon.bz/schema/cbs/archive/errorresource/0")
public class Errorresource

您可以看到名称空间已添加到 @XmlRootElement,如错误消息中所示。


40
投票

您需要将 package-info.java 放入生成的 jaxb 包中。内容应该是这样的

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.example.org/StudentOperations/")
package generated.marsh;

9
投票

经过更多研究后,正如 Blaise 指出的那样,根元素必须与模式命名空间相关联。然而,我没有包信息java。因此,在不使用 @XMLSchema 注释的情况下,我能够通过使用来纠正这个问题

@XmlRootElement (name="RetrieveMultipleSetsResponse", namespace = XMLCodeTable.NS1)
@XmlType(name = "ns0", namespace = XMLCodeTable.NS1)
@XmlAccessorType(XmlAccessType.NONE)
public class RetrieveMultipleSetsResponse {//...}

希望这有帮助!


7
投票

这是针对一个相当小众用例的修复,但每次都让我受益匪浅。如果您使用 Eclipse Jaxb 生成器,它会创建一个名为 package-info.json 的文件。

@javax.xml.bind.annotation.XmlSchema(namespace = "blah.xxx.com/em/feed/v2/CommonFeed")
package xxx.blah.mh.domain.pl3xx.startstop;

如果删除此文件,它将允许解析更通用的 xml。尝试一下!


4
投票

所以当我使用不属于我的 xsd 文件中预先生成的类时,我遇到了例外。

java 类中缺少生成的 xml 对象名称和命名空间(@xmlroot),因此我无法解组它。 像这样将缺少的 URI 放在类上方“解决”了问题:

@XmlRootElement(name = "XHE", namespace = "http://docs.oasis-open.org/bdxr/ns/XHE/1/ExchangeHeaderEnvelope")
public class XHEType {

但是因为我希望这个类只在目标中,所以这还不够。 我最终想出的是这个新类来包装生成的类,我将 @xmlroot 放在其中:

@XmlRootElement(name = "XHE", namespace = "http://docs.oasis-open.org/bdxr/ns/XHE/1/ExchangeHeaderEnvelope")
public class XHEType2  extends XHEType {

以及解组代码:

        JAXBContext jaxbContext = JAXBContext.newInstance(XHEType2.class);
        javax.xml.bind.Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        XHEType xheType = (XHEType) unmarshaller.unmarshal(reader);

2
投票

我遇到了同样的问题..它帮助了我,我指定了与 xml 文件中的标签名称相同的类字段名称(该文件来自外部系统)。

例如:

我的xml文件:

<Response>
  <ESList>
     <Item>
        <ID>1</ID>
        <Name>Some name 1</Name>
        <Code>Some code</Code>
        <Url>Some Url</Url>
        <RegionList>
           <Item>
              <ID>2</ID>
              <Name>Some name 2</Name>
           </Item>
        </RegionList>
     </Item>
  </ESList>
</Response>

我的回应课:

@XmlRootElement(name="Response")
@XmlAccessorType(XmlAccessType.FIELD)
public class Response {
    @XmlElement
    private ESList[] ESList = new ESList[1]; // as the tag name in the xml file..

    // getter and setter here
}

我的 ESList 课程:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="ESList")
public class ESList {
    @XmlElement
    private Item[] Item = new Item[1]; // as the tag name in the xml file..

    // getters and setters here
}

我的物品类别:

@XmlRootElement(name="Item")
@XmlAccessorType(XmlAccessType.FIELD)
public class Item {
    @XmlElement
    private String ID; // as the tag name in the xml file..
    @XmlElement
    private String Name; // and so on...
    @XmlElement
    private String Code;
    @XmlElement
    private String Url;
    @XmlElement
    private RegionList[] RegionList = new RegionList[1];

    // getters and setters here
}

我的 RegionList 类:

@XmlRootElement(name="RegionList")
@XmlAccessorType(XmlAccessType.FIELD)
public class RegionList {
    Item[] Item = new Item[1];

    // getters and setters here
}

我的演示Unmarshalling 类:

public class DemoUnmarshalling {
    public static void main(String[] args) {
        try {
            File file = new File("...");

            JAXBContext jaxbContext = JAXBContext.newInstance(Response.class);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            jaxbUnmarshaller.setEventHandler(
                new ValidationEventHandler() {
                    public boolean handleEvent(ValidationEvent event ) {
                        throw new RuntimeException(event.getMessage(),
                            event.getLinkedException());
                    }
                }
            );

            Response response = (Response) jaxbUnmarshaller.unmarshal(file);

            ESList[] esList = response.getESList();
            Item[] item = esList[0].getItem();
            RegionList[] regionLists = item[0].getRegionList();
            Item[] regionListItem = regionLists[0].getItem();

            System.out.println(item[0].getID());
            System.out.println(item[0].getName());
            System.out.println(item[0].getCode());
            System.out.println(item[0].getUrl());
            System.out.println(regionListItem[0].getID());
            System.out.println(regionListItem[0].getName());

        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }
}

它给出:

1
Some name 1
Some code
Some Url
2
Some name 2

2
投票

这里提到的解决方案都不适合我,我仍然得到:

线程“main”javax.xml.bind.UnmarshalException 中出现异常: 意外元素(uri:“java:XXX.XX.XX.XXX”,本地:“XXXXX”)

经过其他网站的大量研究,下面的代码对我有用-

FileInputStream fis = new FileInputStream("D:/group.xml");
SOAPMessage message = factory.createMessage(new MimeHeaders(), fis);
JAXBContext jc = JAXBContext.newInstance(Group.class);
Unmarshaller u = jc.createUnmarshaller();
JAXBElement<Group> r = u.unmarshal(message.getSOAPBody().extractContentAsDocument(), Group.class);
Group group = r.getValue();

1
投票

如果以上都不起作用,请尝试添加

@XmlRootElement(name="Group")
参加小组课程。


1
投票

您需要将

package-info.java
类放入 contextPath 包中,并将以下代码放入同一个类中:

@javax.xml.bind.annotation.XmlSchema(namespace = "https://www.namespaceUrl.com/xml/", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.test.valueobject;

1
投票

如果您因为这种情况只发生在您的测试中而感到抓狂,并且您正在使用 PowerMock,那么这就是解决方案,请将其添加到您的测试类之上:

@PowerMockIgnore({ "javax.xml.*", "org.xml.*", "org.w3c.*" })

0
投票

我也一样。映射类的名称是

Mbean
,但标签根名称是
mbean
,所以我必须添加注释:

@XmlRootElement(name="mbean")
public class MBean { ... }

0
投票

我也有同样的问题。 我向

<xs:schema..>
添加了以下属性 elementFormDefault="合格" attributeFormDefault="不合格"

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns="http://www.example.com/schemas/ArrayOfMarketWithStations"
    targetNamespace="http://www.example.com/schemas/ArrayOfMarketWithStations" 
    elementFormDefault="qualified" attributeFormDefault="unqualified" >

并通过运行 xjc 重新生成 java 类,从而更正了 package-info.java。

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.example.com/schemas/ArrayOfMarketWithStations", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)

这解决了我的问题。


0
投票

我已经有同样的问题,我只是更改如下:

@XmlRootElement -> @XmlRootElement(name="Group")

0
投票

我有同样的问题,我的问题是,我有两个不同的网络服务和两个不同的 wsdl 文件。我在同一个包中为两个 Web 服务生成了源代码,这似乎是一个问题。我想这是因为 ObjectFactory,也许也是因为 package-info.java - 因为它们只生成一次。

我通过在不同的包中生成每个 Web 服务的源代码解决了这个问题。这样,您还拥有两个不同的 ObjectFactories 和 package-info.java 文件。


0
投票

您很可能没有遇到我遇到的情况。问题是模型类(在 jar 中)具有 javax 包,而处理器(模型类的使用者)wJa 需要 jakarta 包。

© www.soinside.com 2019 - 2024. All rights reserved.