1

我正在尝试使用JAXB来解析以下内容XML。我删除了不相关的部分。不幸的是,原始文件XML是由第三方应用程序生成的,我没有可用DTDXSD文件,所以我正在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”。有什么解决办法吗?

4

2 回答 2

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

值适配器

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;
        }
    }

}

添加属性

package forum13232991;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

public class AddAttr {

    @XmlJavaTypeAdapter(ValueAdapter.class)
    Object value;

}

了解更多信息

于 2012-11-05T13:25:56.120 回答
1

一种方法是创建一个 XSL 转换,它基于 type 属性将 xsi:type 属性添加到 value 元素。然后,您的所有 Value 元素都可以从同一个 BaseValue 类扩展,并且 add-attr 元素可以引用此 BaseValue。

于 2012-11-05T13:30:14.893 回答