Java Jaxb:在同一个包中使用多个名称空间对xml进行解组

Java Jaxb:在同一个包中使用多个名称空间对xml进行解组,java,xml,namespaces,jaxb,annotations,Java,Xml,Namespaces,Jaxb,Annotations,我不熟悉在xml中使用名称空间,所以我有点困惑,希望得到一些澄清。我有一个java服务,在那里我接收到具有许多不同名称空间的xml文档,当我让它工作时,我觉得我一定做错了什么,所以我想检查一下。在我的package-info.java中,我有我的模式注释,例如: @javax.xml.bind.annotation.XmlSchema( xmlns={ @javax.xml.bind.annotation.XmHS(prefix="train", namespaceURI

我不熟悉在xml中使用名称空间,所以我有点困惑,希望得到一些澄清。我有一个java服务,在那里我接收到具有许多不同名称空间的xml文档,当我让它工作时,我觉得我一定做错了什么,所以我想检查一下。在我的package-info.java中,我有我的模式注释,例如:

@javax.xml.bind.annotation.XmlSchema(
    xmlns={
        @javax.xml.bind.annotation.XmHS(prefix="train", namespaceURI="http://mycompany/train"), 
        @javax.xml.bind.annotation.XmHS(prefix="passenger", namespaceURI="http://mycompany/passenger")
    }, 
    elementFormDefault = javax.xml.bind.annotation.XmlNsForm=QUALIFIED
)
我在类级别上有一个Train.java注释:

@XmlRootElement(name="Train", namespace="http://mycompany/train")
类中的每个字段都标注有:

@XmlElement(name="Color") for example
@XmlElementWrapper(name="Passengers")
@XmlElements(@XmlElement(name="Passenger", namespace="http://mycompany/passenger"))
@XmlElement(name="Passenger", namespace="http://mycompany/passenger")
列车包含乘客列表,因此有一个属性

private Set<Passenger> passengers;
然后在Passenger.java中,类本身被注释为:

@XmlElement(name="Color") for example
@XmlElementWrapper(name="Passengers")
@XmlElements(@XmlElement(name="Passenger", namespace="http://mycompany/passenger"))
@XmlElement(name="Passenger", namespace="http://mycompany/passenger")
最后,对于Passenger.java中的各个字段,它们的注释如下:

@XmlElement(name="TicketNumber", namespace="http://mycompany/passenger")
因此,当我有一个xml时,它看起来像:

<train:Train>
   <train:Color>Red</train:Color>
   <train:Passengers>
       <train:Passenger>
           <passenger:TicketNumber>T101</passenger:TicketNumber>
       </train:Passenger>
   </train:Passengers>
</train:Train>

红色
T101

现在我解组了我收到的xml,设置了Train的Color属性,设置了Passenger的TicketNumber属性。但是我不知道为什么我需要在TicketNumber上的xmlement注释上添加名称空间url,这样才能工作,但是我不需要为Train上的Color属性添加名称空间url。如果我从TicketNumber上的XmlElement注释中删除namespace属性,xml中的值将不会映射到对象,除非我也从xml请求中删除了名称空间前缀。我觉得既然我已经在XmlRootElement上为Passenger定义了namespace属性,我就不需要为类中的每个字段都这样做,就像我不必为Train这样做一样,所以我假设我一定设置了错误的内容。有人能给我指出正确的方向吗?谢谢

下面根据您的模型解释了名称空间在中的工作方式

JAVA模型

套餐信息

下面是
@XmlSchema
注释的修改版本。它包含一些关键信息:

  • namespace
    —用于限定全局元素(与
    @XmlRootElement
    @XmlElementDecl
    注释相对应的元素(以及基于
    elementFormDefault
    值的本地元素)的默认命名空间,这些元素没有指定其他命名空间
  • elementFormDefault
    默认情况下,只有全局元素才限定名称空间,但通过将值设置为
    XmlNsForm。限定的
    所有未指定显式名称空间的元素都将限定为
    名称空间
  • xmlns
    是JAXB impl应该用于这些名称空间的首选前缀集(尽管它们可能使用其他前缀)
@XmlSchema(
名称空间=”http://mycompany/train",
elementFormDefault=XmlNsForm.QUALIFIED,
xmlns={
@XmlNs(prefix=“train”,namespaceURI=”http://mycompany/train"), 
@XmlNs(前缀=“乘客”,名称空间URI=”http://mycompany/passenger")
}
)
15772478包;
导入javax.xml.bind.annotation.*;
列车

由于与
Train
类对应的所有元素都对应于
@XmlSchema
注释上指定的
名称空间
,因此我们不需要指定任何名称空间信息

  • 全局元素—
    @XmlRootElement
    注释对应于全局元素
  • 本地元素—
    @xmlementwrapper
    @xmlement
    注释对应于本地元素
UM15772478的包;
导入java.util.List;
导入javax.xml.bind.annotation.*;
@XmlRootElement(name=“Train”)
公车{
私人名单乘客;
@XmlElementWrapper(name=“乘客”)
@XmlElement(name=“乘客”)
公众名单{
返程旅客;
}
公众乘客(名单乘客){
这个。乘客=乘客;
}
}
乘客

如果与
乘客
类上的属性对应的所有元素都将在
http://mycompany/passenger
名称空间,然后可以使用
@XmlType
注释覆盖
@XmlSchema
注释中的
名称空间

UM15772478的包;
导入javax.xml.bind.annotation.*;
@XmlType(命名空间=”http://mycompany/passenger")
公务舱乘客{
私有字符串ticketNumber;
@XmlElement(name=“TicketNumber”)
公共字符串getTicketNumber(){
返回票号;
}
public void setTicketNumber(字符串ticketNumber){
this.ticketNumber=ticketNumber;
}
}
或者,您可以在属性级别重写命名空间

UM15772478的包;
导入javax.xml.bind.annotation.*;
公务舱乘客{
私有字符串ticketNumber;
@XmlElement(
名称空间=”http://mycompany/passenger",
name=“TicketNumber”)
公共字符串getTicketNumber(){
返回票号;
}
public void setTicketNumber(字符串ticketNumber){
this.ticketNumber=ticketNumber;
}
}
演示代码

可以运行以下演示代码来证明一切正常:

演示

UM15772478的包;
导入java.io.File;
导入javax.xml.bind.*;
公开课演示{
公共静态void main(字符串[]args)引发异常{
JAXBContext jc=JAXBContext.newInstance(Train.class);
Unmarshaller Unmarshaller=jc.createUnmarshaller();
File xml=新文件(“src/forum15772478/input.xml”);
Train Train=(Train)unmarshaller.unmarshal(xml);
Marshaller=jc.createMarshaller();
setProperty(marshaller.JAXB_格式化的_输出,true);
编组员。编组员(列车、系统、输出);
}
}
input.xml/Output

在下面的XML中,我添加了XML文档中缺少的必要名称空间声明