我正在尝试使用JAXB
来解析以下XML
。我删除了不相关的部分。很遗憾,原始XML
是由第三方应用生成的,我没有DTD
或XSD
文件可用,因此我手动构建了JAXB
代码。
<add>
<add-attr attr-name="UserName">
<value type="string">User1</value>
</add-attr>
<add-attr attr-name="Name">
<value type="structured">
<component name="familyName">Doe</component>
<component name="givenName">John</component>
</value>
</add-attr>
</add>
问题当然是<value>
元素。这可以是具有纯文本的元素,或者如果其属性类型是“结构化的,<component>
元素的列表。
我创建了两个实现这两个选项的类(value1和value2),但是我不能告诉JAXB
使用哪一个,因为这些元素都被命名为“value”。有没有解决方案?
答案 0 :(得分:2)
选项#1 - 一个价值类
您可以拥有一个Value
类,其中包含一个用String
注释的@XmlMixed
属性。
package forum13232991;
import java.util.List;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Value {
@XmlAttribute
String type;
@XmlMixed
List<String> value;
@XmlElement(name="component")
List<Component> components;
}
选项#2 - 多个价值类通过XmlAdapter
如果您希望它们是单独的类,您可以使用XmlAdapter
来实现此目的:
的 ValueAdapter 强> 的
package forum13232991;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class ValueAdapter extends XmlAdapter<Value, Object> {
@Override
public Value marshal(Object object) throws Exception {
Value value = new Value();
if(object instanceof StructuredValue) {
StructuredValue structuredValue = (StructuredValue) object;
value.type = "structured";
value.components = structuredValue.components;
} else {
StringValue stringValue = (StringValue) object;
value.value.add(stringValue.value);
}
return value;
}
@Override
public Object unmarshal(Value value) throws Exception {
if("string".equals(value.type)) {
StringValue stringValue = new StringValue();
StringBuilder strBldr = new StringBuilder();
for(String string : value.value) {
strBldr.append(string);
}
stringValue.value = strBldr.toString();
return stringValue;
} else {
StructuredValue structuredValue = new StructuredValue();
structuredValue.components = value.components;
return structuredValue;
}
}
}
的 AddAttr 强> 的
package forum13232991;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
public class AddAttr {
@XmlJavaTypeAdapter(ValueAdapter.class)
Object value;
}
了解更多信息
答案 1 :(得分:1)
一种方法是创建一个XSL转换,它根据type属性向值元素添加xsi:type属性。然后,所有Value元素都可以从相同的BaseValue类扩展,add-attr元素可以引用此BaseValue。