Sid*_*kha 8 java xml xsd jaxb marshalling
我正在尝试与第三方系统集成,并且根据对象的类型,返回的XML文档的根元素会发生变化。我正在使用JAXB库进行编组/解组。
根1:
<?xml version="1.0" encoding="UTF-8"?>
<root1 id='1'>
<MOBILE>9831138683</MOBILE>
<A>1</A>
<B>2</B>
</root1>
Run Code Online (Sandbox Code Playgroud)
根2:
<?xml version="1.0" encoding="UTF-8"?>
<root2 id='3'>
<MOBILE>9831138683</MOBILE>
<specific-attr1>1</specific-attr1>
<specific-attr2>2</specific-attr2>
</root2>
Run Code Online (Sandbox Code Playgroud)
我正在使用所有不同的XML将它们映射到通用对象:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "ROW")
public class Row {
@XmlAttribute
private int id;
@XmlElement(name = "MOBILE")
private int mobileNo;
@XmlMixed
@XmlAnyElement
@XmlJavaTypeAdapter(MyMapAdapter.class)
private Map<String, String> otherElements;
}
Run Code Online (Sandbox Code Playgroud)
还有用于将未知值转换为映射的适配器:
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.parsers.DocumentBuilderFactory;
import java.util.HashMap;
import java.util.Map;
public class MyMapAdapter extends XmlAdapter<Element, Map<String, String>> {
private Map<String, String> hashMap = new HashMap<>();
@Override
public Element marshal(Map<String, String> map) throws Exception {
// expensive, but keeps the example simpler
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element root = document.createElement("dynamic-elements");
for(Map.Entry<String, String> entry : map.entrySet()) {
Element element = document.createElement(entry.getKey());
element.setTextContent(entry.getValue());
root.appendChild(element);
}
return root;
}
@Override
public Map<String, String> unmarshal(Element element) {
String tagName = element.getTagName();
String elementValue = element.getChildNodes().item(0).getNodeValue();
hashMap.put(tagName, elementValue);
return hashMap;
}
}
Run Code Online (Sandbox Code Playgroud)
这会将ID和手机号码放在字段中,其余的未知字段则放在地图中。
如上例所示,如果根元素固定为ROW,则此方法有效。
如何使这项工作使根元素在每个XML中都不同?一种可能在解组时不了解根元素的方法?
我认为没有办法做到你所要求的。在 XML 中,根节点(文档)必须具有已定义的元素(或类)。换句话说,xs:any仅适用于子元素。即使有办法实现这一目标,这也是一个错误的决定。您应该向同一元素添加名称属性以区分 XML 文件,而不是创建变量(“动态”)根元素。例如:
<?xml version="1.0" encoding="UTF-8"?>
<ROW id='1' name="me">
<MOBILE>9831138683</MOBILE>
<specific-attr1>1</specific-attr1>
<specific-attr2>2</specific-attr2>
</ROW>
<?xml version="1.0" encoding="UTF-8"?>
<ROW id='2' name="you">
<MOBILE>123456790</MOBILE>
<specific-attr1>3</specific-attr1>
<specific-attr2>4</specific-attr2>
</ROW>
Run Code Online (Sandbox Code Playgroud)
为此,您需要做的就是向现有元素添加一个 name 属性:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "ROW")
public class Row {
@XmlAttribute
private int id;
@XmlAttribute(name = "name", required=true)
private String name;
@XmlElement(name = "MOBILE")
private int mobileNo;
@XmlMixed
@XmlAnyElement
@XmlJavaTypeAdapter(MyMapAdapter.class)
private Map<String, String> otherElements;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
140 次 |
| 最近记录: |