Đây là kịch bản của tôi. Tôi có một lớp generic:Trường trùng lặp trong XML được tạo bằng cách sử dụng JAXB
public class Tuple<T> extends ArrayList<T> {
//...
public Tuple(T ...members) {
this(Arrays.asList(members));
}
@XmlElementWrapper(name = "tuple")
@XmlElement(name = "value")
public List<T> getList() {
return this;
}
}
Và một lớp trẻ:
public class StringTuple extends Tuple<String> {
public StringTuple(String ...members) {
super(members);
}
//explanation of why overriding this method soon ...
@XmlElementWrapper(name = "tuple")
@XmlElement(name = "value")
@Override
public List<String> getList() {
return this;
}
}
Những lớp được tham chiếu ở đây:
@XmlRootElement(namespace = "iv4e.xml.jaxb.model")
public class Relation {
private Tuple<StringTuple> relationVars;
//...
@XmlElementWrapper(name = "allRelationVars")
@XmlElement(name = "relationVarsList")
public Tuple<StringTuple> getRelationVars() {
return relationVars;
}
}
Sau đó, một đối tượng Relation được tạo ra với một cái gì đó như:
Relation rel = new Relation();
rel.setRelationVars(new Tuple<StringTuple>(
new StringTuple("RelationshipVar1"), new StringTuple("RelationshipVar2")));
Sau khi đầm lầy đối tượng này, đầu ra Xml là như sau:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:relation xmlns:ns2="iv4e.xml.jaxb.model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="">
<allRelationVars>
<relationVarsList>
<tuple>
<value xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">RelationshipVar1</value>
</tuple>
<tuple>
<value>RelationshipVar1</value>
</tuple>
</relationVarsList>
<relationVarsList>
<tuple>
<value xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">RelationshipVar2</value>
</tuple>
<tuple>
<value>RelationshipVar2</value>
</tuple>
</relationVarsList>
</allRelationVars>
</ns2:relation>
Vì vậy, các yếu tố value
được nhân đôi !.
Bây giờ, lý do StringTuple lớp đè List<T> getList()
với List<String> getList()
là tránh gây phiền nhiễu tạo ra xmlns:xs
thuộc tính trong mỗi thành viên của danh sách (các value
yếu tố trong tài liệu xml). Nhưng sau đó mọi thành viên của danh sách được hiển thị hai lần trong đầu ra. Rõ ràng, đó là bởi vì cả hai phương pháp cha mẹ ghi đè và phương pháp con được chú thích với @XmlElement
. Vì vậy, câu hỏi chính của tôi là: có một cách để bỏ qua các phương pháp ghi đè được chú thích với @XmlElement
trong Jaxb? (xem xét phương pháp ghi đè cũng được chú thích với @XmlElement
)
Tôi tìm thấy một bài đăng cũ báo cáo vấn đề tương tự: http://old.nabble.com/@XmlElement-on-overridden-methods-td19101616.html, nhưng tôi chưa tìm thấy bất kỳ giải pháp nào. Cũng lưu ý rằng việc thêm chú thích @XmlTransient
vào phương thức getList
ở lớp cha (Tuple<T>
) có thể giải quyết vấn đề này nhưng sẽ tạo ra các vấn đề khác, vì lớp cha không trừu tượng và chỉ được sử dụng một mình trong các ngữ cảnh khác.
Câu hỏi phụ một bên: có thể khai báo thuộc tính xmlns:xs
ở nút gốc thay vì xuất hiện ở mọi nút khi cần thiết không? Tôi biết điều này có thể được thực hiện với các lớp học NamespacePrefixMapper
, nhưng vì nó là một tiêu chuẩn, SUN nội bộ lớp học, tôi thay vì thích sử dụng một cách tiếp cận độc lập thực hiện hơn.
Cảm ơn trước vì đã có phản hồi!
Trước khi tôi nhận được quá xa vào vấn đề này, làm đối tượng miền của bạn cần phải mở rộng 'ArrayList'? Tại sao 'Tuple' mở rộng' ArrayList' thay vì có thuộc tính của kiểu 'ArrayList'? –
Xin chào Blaise !, Tôi đã chọn kế thừa từ ArrayList vì đối tượng Tuple của tôi thực ra là một ArrayList. Tuy nhiên, tôi có thể sống với nó có chứa một ArrayList thay vào đó, mặc dù sau đó tôi sẽ phải thực hiện một số phương pháp đại biểu. Dù sao, điều đó sẽ không giải quyết được vấn đề của tôi vì tôi vẫn sẽ có một lớp chung Tuple, và một StringTuple mở rộng Tuple. –
Sergio
Tôi đã thêm một câu trả lời với một cách tiếp cận có thể được sử dụng để loại bỏ khai báo 'xsi: type'. –