gpt4 book ai didi

java - JAXB - XML 输出中的意外元素

转载 作者:太空宇宙 更新时间:2023-11-04 07:38:43 25 4
gpt4 key购买 nike

我有一个名为 Building 的类(class).

它有一个列表 BuildingBenchAssociation记录 ( List<BuildingBenchAssociation> benches )

BuildingBenchAssociation具有由 buildingId 组成的复合 id和benchIdID 由名为 BuildingBenchAssociationPK 的单独类表示。它只有两个属性 - buildingIdbenchId

这是我在编码 Building 时得到的输出实例

<building buildingId="9">
<benches>
DOMRecord(<?xml version="1.0" encoding="UTF-8"?><buildingBenchAssociation><benchId>245865</benchId><buildingId>9</buildingId></buildingBenchAssociation>)
</benches>
<benches>
DOMRecord(<?xml version="1.0" encoding="UTF-8"?><buildingBenchAssociation><benchId>245866</benchId><buildingId>9</buildingId></buildingBenchAssociation>)
</benches>
<benches>

但我不想要DOMRecord(<?xml version="1.0" encoding="UTF-8"?>出现在输出中。所需的输出是这样的:

<building buildingId="9">
<benches>
<buildingBenchAssociation><benchId>245865</benchId><buildingId>9</buildingId></buildingBenchAssociation>
</benches>
<benches>
<buildingBenchAssociation><benchId>245866</benchId><buildingId>9</buildingId></buildingBenchAssociation>
</benches>
<benches>

出了什么问题以及如何纠正它?我正在使用 Eclipselink MOXy 库。

引用类:

1 级

@Entity
@Table(name="building")
@XmlRootElement
public class Building implements Serializable {
....

private List<BuildingBenchAssociation> benchs = new ArrayList<BuildingBenchAssociation>();

@XmlIDREF
@OneToMany(mappedBy="building")
public List<BuildingBenchAssociation> getBenchs() {
return benchs;
}

public void setBenchs(List<BuildingBenchAssociation> benchs) {
this.benchs = benchs;
}
}

2级

@Entity
@Table(name="building_bench_rel")
@XmlRootElement
public class BuildingBenchAssociation implements Serializable {
private static final long serialVersionUID = 1L;
private BuildingBenchAssociationPK idx;

private Bench bench;
private Building building;
private byte alertFlags;
private byte status;

public BuildingBenchAssociation() {
idx=new BuildingBenchAssociationPK();
}

@XmlID
@XmlPath(".")
@Id
public BuildingBenchAssociationPK getIdx() {
return this.idx;
}

public void setIdx(BuildingBenchAssociationPK id) {
this.idx = id;
}

@Column(name="ALERT_FLAGS")
public byte getAlertFlags() {
return this.alertFlags;
}

public void setAlertFlags(byte alertFlags) {
this.alertFlags = alertFlags;
}

@Column(name="STATUS", insertable=false, updatable=false)
public byte getStatus() {
return this.status;
}

public void setStatus(byte status) {
this.status = status;
}

@XmlIDREF
@ManyToOne
@JoinColumn(name="BENCH_ID",insertable=false,updatable=false)
public Bench getBench() {
return bench;
}


public void setBench(Bench bench) {
this.bench = bench;
this.idx.setBenchId(bench==null?null:bench.getBenchId());
}

@XmlIDREF
@ManyToOne
@JoinColumn(name="BUILDING_ID",insertable=false,updatable=false)
public Building getBuilding() {
return building;
}

public void setBuilding(Building building) {
this.building = building;
this.idx.setBuildingId(building==null?null:building.getBuildingId());
}

}

3级

@Embeddable
@XmlRootElement
public class BuildingBenchAssociationPK implements Serializable {
...

private Integer buildingId;
private Integer benchId;

public BuildingBenchAssociationPK() {
}

@XmlKey
@Column(name="BUILDING_ID")
public Integer getBuildingId() {
return this.buildingId;
}
public void setBuildingId(Integer buildingId) {
this.buildingId = buildingId;
}

@XmlKey
@Column(name="BENCH_ID")
public Integer getBenchId() {
return this.benchId;
}
public void setBenchId(Integer benchId) {
this.benchId = benchId;
}
}

最佳答案

以下是当前如何使用 MOXy 映射此用例。我已提出以下增强请求,以使该用例更易于映射:

<小时/>

引用对象

嵌入式 ID (EmployeeId)

下面是嵌入 ID 类的示例:

import java.math.BigDecimal;
import javax.persistence.*;
import javax.xml.bind.annotation.*;

@Embeddable
@XmlAccessorType(XmlAccessType.FIELD)
public class EmployeeId {

@Column(name="E_ID")
BigDecimal eId;

String country;

}

具有嵌入式 ID 的类(员工)

我们希望使用嵌入的 ID 类作为 XML 关系中的键。目前 MOXy 不允许通过注释来完成此操作,因此我们将利用 @XmlCustomizer 注释以编程方式修改元数据。

import java.util.List;
import javax.persistence.*;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;

@Entity
@IdClass(EmployeeId.class)
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlCustomizer(EmployeeCustomizer.class)
public class Employee {

@EmbeddedId
@XmlPath(".")
EmployeeId id;

@OneToMany(mappedBy="contact")
List<PhoneNumber> contactNumber;

}

自定义员工的映射元数据 (EmployeeCustomizer)

在定制器类中,我们将为组成嵌入类上的键的映射指定 XPath。

import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;

public class EmployeeCustomizer implements DescriptorCustomizer {

@Override
public void customize(ClassDescriptor descriptor) throws Exception {
descriptor.addPrimaryKeyFieldName("eId/text()");
descriptor.addPrimaryKeyFieldName("country/text()");
}

}
<小时/>

引用对象

电话号码

我们还需要以编程方式添加基于复合键的映射,因此我们将再次使用 @XmlCustomizer 注释。

import javax.persistence.*;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;

@Entity
@XmlAccessorType(XmlAccessType.FIELD)
@XmlCustomizer(PhoneNumberCustomizer.class)
public class PhoneNumber {

@ManyToOne
@JoinColumns({
@JoinColumn(name="E_ID", referencedColumnName = "E_ID"),
@JoinColumn(name="E_COUNTRY", referencedColumnName = "COUNTRY")
})
Employee contact;

}

自定义 PhoneNumber 的映射元数据 (PhoneNumberCustomizer)

在此定制器中,我们将删除默认映射,并根据复合键以编程方式创建新映射。

import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMapping;

public class PhoneNumberCustomizer implements DescriptorCustomizer {

@Override
public void customize(ClassDescriptor descriptor) throws Exception {
descriptor.removeMappingForAttributeName("contact");

XMLObjectReferenceMapping contactMapping = new XMLObjectReferenceMapping();
contactMapping.setAttributeName("contact");
contactMapping.setReferenceClass(Employee.class);
contactMapping.addSourceToTargetKeyFieldAssociation("contact/@eID", "eId/text()");
contactMapping.addSourceToTargetKeyFieldAssociation("contact/@country", "country/text()");
descriptor.addMapping(contactMapping);
}

}
<小时/>

演示代码

以下演示代码可用于演示一切正常:

演示

import java.io.File;
import javax.xml.bind.*;

public class Demo {

public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Employee.class);

Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("input.xml");
Employee employee = (Employee) unmarshaller.unmarshal(xml);

Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(employee, System.out);
}

}

输入.xml/输出

<?xml version="1.0" encoding="UTF-8"?>
<employee>
<eId>10</eId>
<country>Canada</country>
<contactNumber>
<contact eID="10" country="Canada"/>
</contactNumber>
<contactNumber>
<contact eID="10" country="Canada"/>
</contactNumber>
</employee>
<小时/>

了解更多信息

关于java - JAXB - XML 输出中的意外元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16399724/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com