Reputation: 5648
Here is what I am trying to do:
XML is this:
<Doctype1>
<Outter>
<Inner>
<ProblemType>
<foo>...</foo>
<baz>...</baz>
</ProblemType>
</Inner>
</Outter>
</Doctype1>
<-- However, I have: -->
<Doctype2>
<Outter>
<Inner>
<ProblemType>
<blah>...</blah>
<whatever>...</whatever>
</ProblemType>
</Inner>
</Outter>
</Doctype1>
and Share most of the same fields, but in the case of Doctype1 I need ProblemType1 and in Doctype2 I need ProblemType2.
I want to be able to reuse the classes I bind to for and as they are a common tag across all doc types.
@XmlAccessorType(XmlAccessType.FIELD)
public class Doc1{
@XmlElement(name = "Outter")
public List<Outter> outtards;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class Outter {
@XmlElement(name = "Inner")
public List<Innard> innards;
}
@XmlAccessorType(XmlAccessType.FIELD)
public class Innard{
// need to change this if it's Doc1 or Doc2.
//The subtype of problem type needs to change based on DocX
// the element type name won't change
@XmlElement(name = "Inner")
public ProblemType subtype;
}
It seems like Maybe a factory is in order?
@XmlType(factoryClass= , factoryMethod=)
Upvotes: 0
Views: 192
Reputation: 43651
This is a follow-up to this answer in an attempt to save few lines with the @XmlElementWrapper
. Since the Outter
class seems to have no meaning on its own and it serves only as a container for the Inner
class, it may be avoided:
Please try the following:
@XmlAccessorType(XmlAccessType.NONE)
public class Doc1 {
@XmlElementWrapper(name = "Outter")
@XmlElement(type = Inner1.class, name = "Inner")
public List<Inner> getInner() {
return super.getInner();
}
@Override
public void setInner(List<Inner> innards) {
super.setInner(innards);
}
public static class Inner1 extends Inner<ProblemType1> {
@Override
@XmlElement(type = ProblemType1.class, name = "ProblemType")
public List<ProblemType> getProblemTypes() {
return super.getProblemTypes();
}
@Override
public void setProblemTypes(List<ProblemType> problemTypes) {
super.setProblemTypes(problemTypes);
}
}
}
However mind that this now a single list, not a list-of-lists. So this must be still possible with this construct:
<Doctype1>
<Outter>
<Inner>
<ProblemType .../>
</Inner>
<Inner>
<ProblemType .../>
</Inner>
</Outter>
</Doctype1>
But this is not:
<Doctype1>
<Outter>
<Inner>
<ProblemType .../>
</Inner>
</Outter>
<Outter>
<Inner>
<ProblemType .../>
</Inner>
</Outter>
</Doctype1>
Upvotes: 0
Reputation: 5648
@XmlAccessorType(XmlAccessType.NONE)
public class Doc1 {
@XmlElement(type = Outter1.class, name = "Outter")
private List<Outter> outters;
public static class Outter1 extends Outter {
@Override
@XmlElement(type = Inner1.class, name = "Inner")
public List<Inner> getInner() {
return super.getInner();
}
@Override
public void setInner(List<Inner> innards) {
super.setInner(innards);
}
public static class Inner1 extends Inner<ProblemType1> {
@Override
@XmlElement(type = ProblemType1.class, name = "ProblemType")
public List<ProblemType> getProblemTypes() {
return super.getProblemTypes();
}
@Override
public void setProblemTypes(List<ProblemType> problemTypes) {
super.setProblemTypes(problemTypes);
}
}
}
}
other class
public class Doc2 {
@XmlElement(type = Outter2.class, name= "Outter")
private List<Outter> outters;
public static class Outter2 extends Outter {
@Override
@XmlElement(type = Outter2.class, name = "Inner")
public List<Inner> getInner() {
return super.getInner();
}
@Override
public void setInner(List<Inner> innards) {
super.setInner(groups);
}
public static class Inner1 extends Inner<ProblemType2> {
@Override
@XmlElement(type = ProblemType2.class, name = "ProblemType")
public List<ProblemType> getProblemTypes() {
return super.getProblemTypes();
}
@Override
public void setProblemTypes(List<ProblemType> transactions) {
super.setProblemTypes(transactions);
}
}
}
}
I have spent some time trying to reduce it but it doesn't seem to respond to XmlAccesorType.FIELD. If I use the same property name as the super or not it doesn't matter.
Upvotes: 1
Reputation: 43651
First of all, how would you implement such a structure in Java? There's some distance between DoctypeX
and ProblemTypeX
, so you can't polyform directly.
Probably with a structure like (very pseudo-code):
class AbstractDoctype {
AbstractOuter getOuter();
}
class AbstractOuter {
AbstractInner getInner();
}
class AbstractInner {
AbstractProblemType getProblemType();
}
class AbstractProblemType {
}
class Doctype1 extends AbstractDoctype {
Outer1 getOuter();
}
class Outer1 extends AbstractOuter {
Inner1 getInner();
}
class Inner1 extends AbstractInner {
ProblemType1 getProblemType();
}
class ProblemType1 extends AbstractProblemType {
}
class Doctype2 extends AbstractDoctype {
Outer2 getOuter();
}
class Outer2 extends AbstractOuter {
Inner2 getInner();
}
class Inner2 extends AbstractInner {
ProblemType2 getProblemType();
}
class ProblemType2 extends AbstractProblemType {
}
This kind of structure will be then suitable for your XML. You can probably avoid Outer1
/Outer2
using an @XmlElementWrapper
, but you'll still need Inner1
/Inner2
.
Upvotes: 1