我在编组时使用variable vQuery = " where condition";
select * from table1 " + vQuery;
select * from table2 " + vQuery;
select * from table3 " + vQuery;
将@XmlJavaTypeAdapter
个对象转换为Map<Key, Value>
,而在取消编组时将其转换为List<Value>
然后我获得的XML:
<map>
<value>VALUE1</value>
...
</map>
我的问题是:如何摆脱周围的标签以获取
<value>VALUE1</value>
Bean类
@XmlAccessorType(XmlAccessType.FIELD)
public class Data implements Serializable {
/**
* Constant for data value default name
*/
public static final String DATA_VALUE_DEFAULT_NAME = "result";
/**
* Serial version UID
*/
private static final long serialVersionUID = 7387937212735185585L;
/**
* key
*/
@XmlAttribute
private String key;
/**
* name
*/
@XmlAttribute
private String name;
/**
* Map of data
*/
@XmlJavaTypeAdapter(MapDataAdapter.class)
private Map<String, Data> dataMap;
/**
* Constructor
*/
public Data() {
}
}
适配器
public class MapDataAdapter
extends XmlAdapter<MapDataAdapter.AdaptedDataMap,
Map<String, Data>> {
/**
* Adapted map
*/
public static class AdaptedDataMap {
/**
* List of entry
*/
@XmlElement(name = "data", required = true)
protected List<Data> entry = new ArrayList<>();
}
/**
* {@inheritDoc}
*/
@Override
public Map<String, Data> unmarshal(
AdaptedDataMap adaptedMap) throws Exception {
if (adaptedMap == null) {
return null;
}
Map<String, Data> map = new HashMap<>(adaptedMap.entry.size());
for (Data entry : adaptedMap.entry) {
map.put(entry.getKey(), entry);
}
return map;
}
/**
* {@inheritDoc}
*/
@Override
public AdaptedDataMap marshal(
Map<String, Data> map) throws Exception {
if (map == null) {
return null;
}
AdaptedDataMap adaptedMap = new AdaptedDataMap();
for (Entry<String, Data> mapEntry : map.entrySet()) {
adaptedMap.entry.add(mapEntry.getValue());
}
return adaptedMap;
}
}
XML输出
<data key="12" name="TEST1">
<dataMap>
<data key="text" name="TEST2">
<dataMap>
<data key="azerty" name="TEST3">
</data>
</dataMap>
</data>
</dataMap>
</data>
我需要什么
<data key="12" name="TEST1">
<data key="text" name="TEST2">
<data key="azerty" name="TEST3">
</data>
</data>
</data>
答案 0 :(得分:0)
要在没有元素包装器的情况下将元素从地图中编组/拆组,可以实现一个List,该列表将数据存储在Map中。 JAXB会将其视为简单列表,并且知道如何处理。
我开发此方法是因为@XmlJavaTypeAdapter
似乎与@XmlElements
或@XmlElementRefs
不兼容。实际上,javadocs说@XmlJavaTypeAdapter
可以与@XmlElementRefs
结合使用,但是它对我没有用。我一直在抓ClassCastException。
替代方法立即解决了两个问题:
@XmlRootElement(name="example-document")
@XmlAccessorType(XmlAccessType.NONE)
public class ExampleDocument
{
@XmlElements
(
{
@XmlElement( name="child1" type=Child1.class ),
@XmlElement( name="child2", type=Child2.class )
}
)
private ChildrenList children = new ChildrenList();
public Children getChildById( String id )
{
return children.getMap().get( id );
}
public Collection<Children> allChildren()
{
return children.getMap().values();
}
}
@XmlTransient
public class Children
{
private String id;
}
@XmlType
public class Child1 extends Children
{
}
@XmlType
public class Child2 extends Children
{
}
public class ChildList implements List<Children>
{
private Map<String,Children> map
= new TreeMap<String,Children>();
@Override
public boolean add( Children c )
{
return map.put( c.getId(), c ) != null;
}
@Override
public boolean remove( Object o )
{
return map.remove( ((Children)o).getId() ) != null;
}
@Override
public int size()
{
return map.size();
}
@Override
public boolean isEmpty()
{
return map.isEmpty();
}
@Override
public boolean contains( Object o )
{
return map.containsKey( ((Children)o).getId() );
}
@Override
public Iterator<Children> iterator()
{
return map.values().iterator();
}
@Override
public Object[] toArray()
{
return map.values().toArray();
}
@Override
public <T> T[] toArray( T[] ts )
{
return map.values().toArray( ts );
}
@Override
public boolean addAll( Collection<? extends ArticleBiblio> collection )
{
boolean result = false;
for( ArticleBiblio b : collection )
{
result |= add( b );
}
return result;
}
/* all other methods throws UnsupportedOperationException */
}
答案 1 :(得分:0)
我喜欢Lucas的解决方案,并通过使其通用以防止不必要的类型检查在此进行扩展。
列表项抽象类
abstract class MapListItem<K> {
/* Note that we can't implement this here, because we may want to rename or restructure the key attribute in the XML */
public abstract K getKey();
}
示例商品类别
public class ItemA extends MapListItem<String>{
@XmlAttribute(name="keyA")
public String key;
@XmlElement(name = "valueA")
public ArrayList<ValueA> values = new ArrayList<>();
public ItemA(String key) {
this.key = key;
}
public ItemA(String key, ArrayList<ValueA> values) {
this(key);
this.values = values;
}
@Override
public String getKey() {
return key;
}
}
通用地图列表-K是键类型,V是值类型,还包含一个键。
public class MapList<K, V extends MapListItem<K>> implements List<V> {
private Map<K, V> map = new TreeMap<>();
public MapList(Collection<? extends V> collection) {
addAll(collection);
}
@Override
public boolean add(V c) {
return map.put(c.getKey(), c) != null;
}
@Override
public boolean remove(Object o) {
return map.remove(((V) o).getKey()) != null;
}
@Override
public int size() {
return map.size();
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
@Override
public boolean contains(Object o) {
return map.containsKey(((V) o).getKey());
}
@Override
public Iterator<V> iterator() {
return map.values().iterator();
}
@Override
public Object[] toArray() {
return map.values().toArray();
}
@Override
public <T> T[] toArray(T[] ts) {
return map.values().toArray(ts);
}
@Override
public boolean addAll(Collection<? extends V> collection) {
boolean result = false;
for (V b : collection) {
result |= add(b);
}
return result;
}
}
现在,我们可以像这样创建一个MapList:
@XmlElement(name = "itemA")
public MapList<String,ItemA> itemAs;