我正在尝试创建 JAXB 注释类以基于 Microsoft SharePoint Query schema 生成 XML .我有一个 SpWhereClause
类:
@XmlType(name="Where")
@XmlAccessorType(XmlAccessType.FIELD)
public class SpWhereClause {
}
但我不确定如何构建/注释其属性。 <Where>
element 可以有许多不同类型的子元素( <Eq>
、 <BeginsWith>
、 <Contains>
等。让我们暂时忽略 <And>
和 <Or>
),但不能超过一个。 Eq
和 BeginsWith
每个单独都是Where
的有效子代,但它不能是这样的:
<Where>
<Eq>...</Eq>
<BeginsWith>...</BeginsWith>
</Where>
没有嵌套 <Eq>
和 <BeginsWith>
在<Or>
元素。
我的第一个想法是创建一个 AbstractSpComparison
类与 <FieldRef>
和 <Value>
所有比较共有的元素:
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class AbstractSpComparison {
@XmlElement
private SpFieldRef fieldRef;
@XmlElement
private SpValue value;
...
}
然后有 SpEqualsComparison
扩展它:
@XmlType(name="Eq")
public class SpEqualsComparison extends AbstractSpComparison {
}
但是,使用SpWhereClause
中的抽象类让我无法控制子元素的名称。这:
@XmlElement
private AbstractSpComparison comparison;
结果:
<Where>
<comparison>...</comparison>
</Where>
而不是这个:
<WHERE>
<Eq>...</Eq>
</WHERE>
为什么“Eq”名称不是来自 SpEqualsComparison
被用来命名比较元素?处理这种情况的正确方法是什么?
我考虑过将所有可能的子元素类型作为 SpWhereClause
的属性,并且只设置我需要的那个(在某处有一些验证逻辑),但这似乎不必要地冗长。
如果重要的话,我使用的是 Spring OXM Jaxb2Marshaller
.
最佳答案
您可以执行几个不同的选项:
选项 #1 - @XmlElementRef
如果一切都扩展了一个公共(public)父类(super class)(即 AbstractSpComparison),那么您可以利用 @XmlElementRef
注释。执行此操作时,子元素将对应于引用对象类上的 @XmlRootElement
注释的值。
@XmlElementRef
private AbstractSpComparison comparison;
了解更多信息
我在我的博客上写了更多关于这种方法的文章:
选项 #2 - @XmlElements
如果一切都没有扩展一个通用的父类(super class),那么您可以利用 @XmlElements
注释,您可以在其中显式注释哪些元素可能出现以及它们对应于哪个类:
@XmlElements({
@XmlElement(name="Eq", type=Eq.class),
@XmlElement(name="BeginsWith", type=BeginsWith.class)
})
private AbstractSpComparison comparison;
了解更多信息
我在我的博客上写了更多关于这种方法的文章:
关于java - 使用 JAXB 编码只能包含多个子节点类型之一的 XML 节点(SharePoint 查询),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24168673/