JAXB: 마샬이 가치 를 창출하는 방법
JAXB 맵 마샬링에 대한 질문입니다. 맵을 다음과 같은 구조로 마샬링하는 방법에 대한 많은 예가 있습니다.
<map>
<entry>
<key> KEY </key>
<value> VALUE </value>
</entry>
<entry>
<key> KEY2 </key>
<value> VALUE2 </value>
</entry>
<entry>
...
</map>
사실, 이것은 JAXB가 기본적으로 지원합니다.하지만 필요한 것은 XML입니다. 여기서 key는 요소 이름이고 value는 내용입니다.
<map>
<key> VALUE </key>
<key2> VALUE2 </key2>
...
</map>
JAXB 개발자가 권장하는 방식으로 맵 어댑터를 구현하는 데 성공하지 못했습니다(https://jaxb.dev.java.net/guide/Mapping_your_favorite_class.html), 필요에 따라 he - dynamic 속성 이름 :).
그것에 대한 해결책이 있습니까?
추신. 현재 XML에 마샬링하고 싶은 각 일반적인 키-값 쌍 집합에 대한 전용 컨테이너 클래스를 만들어야 합니다. 효과는 있지만 이러한 도우미 컨테이너를 너무 많이 만들어야 합니다.
이 작업을 수행하려는 타당한 이유가 있을 수 있지만 이러한 XML을 생성하는 것은 일반적으로 피하는 것이 좋습니다.왜 그럴까요? 지도의 XML 요소는 지도의 런타임 내용에 따라 달라지기 때문입니다.그리고 XML은 일반적으로 외부 인터페이스 또는 인터페이스 계층으로 사용되기 때문에 바람직하지 않습니다.제가 설명해 드릴게요.
XML 스키마(xsd)는 XML 문서의 인터페이스 계약을 정의합니다.JAXB는 XSD에서 코드를 생성할 수 있을 뿐만 아니라 코드에서 XML 스키마를 생성할 수도 있습니다.이를 통해 인터페이스를 통해 교환되는 데이터를 XSD에 정의된 사전 합의된 구조로 제한할 수 있습니다.
인 의 Map<String, String>
맵가 여러 합니다. 이 은 각각 의 엔트리 요소를 . 이 요소들은 는 XSD 가 의 를 하도록 할 이며 해야 를 은 된 해야 를 은 된 .xs:string
와 하나의와xs:string
가치가 있네요 꽤 명확한 인터페이스 계약이네요
설명하는 내용은 xml 맵에 실행 시 맵의 내용에 따라 이름이 결정되는 요소가 포함되도록 하는 것입니다.그러면 생성된 XSD는 컴파일 시에 유형을 알 수 없는 요소의 목록을 맵에 포함해야 한다고만 지정할 수 있습니다.이는 인터페이스 계약을 정의할 때 일반적으로 피해야 할 사항입니다.
이 경우 엄격한 계약을 달성하려면 String 대신 열거형을 맵의 키로 사용해야 합니다.예.
public enum KeyType {
KEY, KEY2;
}
@XmlJavaTypeAdapter(MapAdapter.class)
Map<KeyType , String> mapProperty;
이렇게 XML에서 요소가 되고 싶은 키는 컴파일 시에 알 수 있으므로 JAXB는 미리 정의된 키 중 하나인 KEY 또는 KEY2를 사용하여 맵의 요소를 요소로 제한하는 스키마를 생성할 수 있어야 합니다.
반면에 기본 생성 구조를 단순화하려는 경우
<map>
<entry>
<key>KEY</key>
<value>VALUE</value>
</entry>
<entry>
<key>KEY2</key>
<value>VALUE2</value>
</entry>
</map>
이런 단순한 것에
<map>
<item key="KEY" value="VALUE"/>
<item key="KEY2" value="VALUE2"/>
</map>
다음과 같이 맵을 MapElements 배열로 변환하는 MapAdapter를 사용할 수 있습니다.
class MapElements {
@XmlAttribute
public String key;
@XmlAttribute
public String value;
private MapElements() {
} //Required by JAXB
public MapElements(String key, String value) {
this.key = key;
this.value = value;
}
}
public class MapAdapter extends XmlAdapter<MapElements[], Map<String, String>> {
public MapAdapter() {
}
public MapElements[] marshal(Map<String, String> arg0) throws Exception {
MapElements[] mapElements = new MapElements[arg0.size()];
int i = 0;
for (Map.Entry<String, String> entry : arg0.entrySet())
mapElements[i++] = new MapElements(entry.getKey(), entry.getValue());
return mapElements;
}
public Map<String, String> unmarshal(MapElements[] arg0) throws Exception {
Map<String, String> r = new TreeMap<String, String>();
for (MapElements mapelement : arg0)
r.put(mapelement.key, mapelement.value);
return r;
}
}
제공된 코드가 저에게는 통하지 않았습니다.지도를 만드는 다른 방법을 찾았습니다.
맵 요소:
package com.cellfish.mediadb.rest.lucene;
import javax.xml.bind.annotation.XmlElement;
class MapElements
{
@XmlElement public String key;
@XmlElement public Integer value;
private MapElements() {} //Required by JAXB
public MapElements(String key, Integer value)
{
this.key = key;
this.value = value;
}
}
맵 어댑터:
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.adapters.XmlAdapter;
class MapAdapter extends XmlAdapter<MapElements[], Map<String, Integer>> {
public MapElements[] marshal(Map<String, Integer> arg0) throws Exception {
MapElements[] mapElements = new MapElements[arg0.size()];
int i = 0;
for (Map.Entry<String, Integer> entry : arg0.entrySet())
mapElements[i++] = new MapElements(entry.getKey(), entry.getValue());
return mapElements;
}
public Map<String, Integer> unmarshal(MapElements[] arg0) throws Exception {
Map<String, Integer> r = new HashMap<String, Integer>();
for (MapElements mapelement : arg0)
r.put(mapelement.key, mapelement.value);
return r;
}
}
루트 요소:
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
public class Root {
private Map<String, Integer> mapProperty;
public Root() {
mapProperty = new HashMap<String, Integer>();
}
@XmlJavaTypeAdapter(MapAdapter.class)
public Map<String, Integer> getMapProperty() {
return mapProperty;
}
public void setMapProperty(Map<String, Integer> map) {
this.mapProperty = map;
}
}
이 웹사이트 http://www.developpez.net/forums/d972324/java/general-java/xml/hashmap-jaxb/ 에서 코드를 찾았습니다.
더 나은 솔루션을 개발 중이지만 MOXy JAXB를 사용하면 다음 XML을 처리할 수 있습니다.
<?xml version="1.0" encoding="UTF-8"?>
<root>
<mapProperty>
<map>
<key>value</key>
<key2>value2</key2>
</map>
</mapProperty>
</root>
지도 속성에서 @XmlJavaTypeAdapter를 사용해야 합니다.
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
public class Root {
private Map<String, String> mapProperty;
public Root() {
mapProperty = new HashMap<String, String>();
}
@XmlJavaTypeAdapter(MapAdapter.class)
public Map<String, String> getMapProperty() {
return mapProperty;
}
public void setMapProperty(Map<String, String> map) {
this.mapProperty = map;
}
}
XmlAdapter의 구현은 다음과 같습니다.
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class MapAdapter extends XmlAdapter<AdaptedMap, Map<String, String>> {
@Override
public AdaptedMap marshal(Map<String, String> map) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.newDocument();
Element rootElement = document.createElement("map");
document.appendChild(rootElement);
for(Entry<String,String> entry : map.entrySet()) {
Element mapElement = document.createElement(entry.getKey());
mapElement.setTextContent(entry.getValue());
rootElement.appendChild(mapElement);
}
AdaptedMap adaptedMap = new AdaptedMap();
adaptedMap.setValue(document);
return adaptedMap;
}
@Override
public Map<String, String> unmarshal(AdaptedMap adaptedMap) throws Exception {
Map<String, String> map = new HashMap<String, String>();
Element rootElement = (Element) adaptedMap.getValue();
NodeList childNodes = rootElement.getChildNodes();
for(int x=0,size=childNodes.getLength(); x<size; x++) {
Node childNode = childNodes.item(x);
if(childNode.getNodeType() == Node.ELEMENT_NODE) {
map.put(childNode.getLocalName(), childNode.getTextContent());
}
}
return map;
}
}
AdpatedMap 클래스는 모든 마법이 일어나는 곳입니다. 컨텐츠를 표현하기 위해 DOM을 사용합니다.@XmlAnyElement와 Object 유형의 속성을 결합하여 JAXB가 DOM을 처리하도록 속입니다.
import javax.xml.bind.annotation.XmlAnyElement;
public class AdaptedMap {
private Object value;
@XmlAnyElement
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
이 솔루션에는 MOXy JAXB 구현이 필요합니다.모델 클래스에 다음 항목을 포함하여 jaxb.properties라는 파일을 추가하여 MOXy 구현을 사용하도록 JAXB 런타임을 구성할 수 있습니다.
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
다음 데모 코드를 사용하여 코드를 확인할 수 있습니다.
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Root root = (Root) unmarshaller.unmarshal(new File("src/forum74/input.xml"));
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
저는 이것에 대해 잘 대답하는 것을 보지 못했습니다.여기서 꽤 효과적인 걸 찾았어요
JAXB XMLanyElement 유형의 스타일을 사용하여 동적 요소 이름을 반환합니다.
해시맵 트리를 지원하기 위해 조금 수정했습니다.다른 컬렉션을 추가할 수 있습니다.
public class MapAdapter extends XmlAdapter<MapWrapper, Map<String, Object>> {
@Override
public MapWrapper marshal(Map<String, Object> m) throws Exception {
MapWrapper wrapper = new MapWrapper();
List elements = new ArrayList();
for (Map.Entry<String, Object> property : m.entrySet()) {
if (property.getValue() instanceof Map)
elements.add(new JAXBElement<MapWrapper>(new QName(getCleanLabel(property.getKey())),
MapWrapper.class, marshal((Map) property.getValue())));
else
elements.add(new JAXBElement<String>(new QName(getCleanLabel(property.getKey())),
String.class, property.getValue().toString()));
}
wrapper.elements = elements;
return wrapper;
}
@Override
public Map<String, Object> unmarshal(MapWrapper v) throws Exception {
HashMap<String, Object> returnval = new HashMap();
for (Object o : v.elements) {
Element e = (Element) o;
if (e.getChildNodes().getLength() > 1) {
MapWrapper mw = new MapWrapper();
mw.elements = new ArrayList();
for (int count = 0; count < e.getChildNodes().getLength(); count++) {
if (e.getChildNodes().item(count) instanceof Element) {
mw.elements.add(e.getChildNodes().item(count));
}
}
returnval.put(e.getTagName(), unmarshal(mw));
} else {
returnval.put(e.getTagName(), e.getTextContent());
}
}
return returnval;
}
// Return a XML-safe attribute. Might want to add camel case support
private String getCleanLabel(String attributeLabel) {
attributeLabel = attributeLabel.replaceAll("[()]", "").replaceAll("[^\\w\\s]", "_").replaceAll(" ", "_");
return attributeLabel;
}
}
class MapWrapper {
@XmlAnyElement
List elements;
}
그런 다음 구현 방법을 구현합니다.
static class myxml {
String name = "Full Name";
String address = "1234 Main St";
// I assign values to the map elsewhere, but it's just a simple
// hashmap with a hashmap child as an example.
@XmlJavaTypeAdapter(MapAdapter.class)
public Map<String, Object> childMap;
}
간단한 마샬러를 통해 이것을 공급하면 다음과 같은 결과를 얻을 수 있습니다.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<myxml>
<name>Full Name</name>
<address>1234 Main St</address>
<childMap>
<key2>value2</key2>
<key1>value1</key1>
<childTree>
<childkey1>childvalue1</childkey1>
</childTree>
</childMap>
</myxml>
어댑터가 없는 해결책이 있습니다.임시 맵이 xml-elements로 변환되거나 그 반대의 경우:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "SchemaBasedProperties")
public class SchemaBasedProperties
{
@XmlTransient
Map<String, Map<String, String>> properties;
@XmlAnyElement(lax = true)
List<Object> xmlmap;
public Map<String, Map<String, String>> getProperties()
{
if (properties == null)
properties = new LinkedHashMap<String, Map<String, String>>(); // I want same order
return properties;
}
boolean beforeMarshal(Marshaller m)
{
try
{
if (properties != null && !properties.isEmpty())
{
if (xmlmap == null)
xmlmap = new ArrayList<Object>();
else
xmlmap.clear();
javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
org.w3c.dom.Document doc = db.newDocument();
org.w3c.dom.Element element;
Map<String, String> attrs;
for (Map.Entry<String, Map<String, String>> it: properties.entrySet())
{
element = doc.createElement(it.getKey());
attrs = it.getValue();
if (attrs != null)
for (Map.Entry<String, String> at: attrs.entrySet())
element.setAttribute(at.getKey(), at.getValue());
xmlmap.add(element);
}
}
else
xmlmap = null;
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
return true;
}
void afterUnmarshal(Unmarshaller u, Object p)
{
org.w3c.dom.Node node;
org.w3c.dom.NamedNodeMap nodeMap;
String name;
Map<String, String> attrs;
getProperties().clear();
if (xmlmap != null)
for (Object xmlNode: xmlmap)
if (xmlNode instanceof org.w3c.dom.Node)
{
node = (org.w3c.dom.Node) xmlNode;
nodeMap = node.getAttributes();
name = node.getLocalName();
attrs = new HashMap<String, String>();
for (int i = 0, l = nodeMap.getLength(); i < l; i++)
{
node = nodeMap.item(i);
attrs.put(node.getNodeName(), node.getNodeValue());
}
getProperties().put(name, attrs);
}
xmlmap = null;
}
public static void main(String[] args)
throws Exception
{
SchemaBasedProperties props = new SchemaBasedProperties();
Map<String, String> attrs;
attrs = new HashMap<String, String>();
attrs.put("ResId", "A_LABEL");
props.getProperties().put("LABEL", attrs);
attrs = new HashMap<String, String>();
attrs.put("ResId", "A_TOOLTIP");
props.getProperties().put("TOOLTIP", attrs);
attrs = new HashMap<String, String>();
attrs.put("Value", "hide");
props.getProperties().put("DISPLAYHINT", attrs);
javax.xml.bind.JAXBContext jc = javax.xml.bind.JAXBContext.newInstance(SchemaBasedProperties.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(props, new java.io.File("test.xml"));
Unmarshaller unmarshaller = jc.createUnmarshaller();
props = (SchemaBasedProperties) unmarshaller.unmarshal(new java.io.File("test.xml"));
System.out.println(props.getProperties());
}
}
내 출력은 다음과 같습니다.
<SchemaBasedProperties>
<LABEL ResId="A_LABEL"/>
<TOOLTIP ResId="A_TOOLTIP"/>
<DISPLAYHINT Value="hide"/>
</SchemaBasedProperties>
{LABEL={ResId=A_LABEL}, TOOLTIP={ResId=A_TOOLTIP}, DISPLAYHINT={Value=hide}}
요소 이름/값 쌍을 사용할 수 있습니다.속성이 필요해요...재미있게 보내!
(미안합니다, 댓글을 추가할 수 없습니다)
위의 블레즈의 답변에서, 변경할 경우:
@XmlJavaTypeAdapter(MapAdapter.class)
public Map<String, String> getMapProperty() {
return mapProperty;
}
대상:
@XmlJavaTypeAdapter(MapAdapter.class)
@XmlPath(".") // <<-- add this
public Map<String, String> getMapProperty() {
return mapProperty;
}
그러면 이것은 제거될 것입니다.<mapProperty>
태그를 지정하면 다음을 제공합니다.
<?xml version="1.0" encoding="UTF-8"?>
<root>
<map>
<key>value</key>
<key2>value2</key2>
</map>
</root>
또는:
다음으로 변경할 수도 있습니다.
@XmlJavaTypeAdapter(MapAdapter.class)
@XmlAnyElement // <<-- add this
public Map<String, String> getMapProperty() {
return mapProperty;
}
그리고 나서 당신은 그들을 제거할 수 있습니다.AdaptedMap
,고냥다다e냥t고이t,d,r MapAdapter
에 마셜을 바르다Document
직접적으로 반대합니다.저는 이것을 마샬링으로만 테스트해봤기 때문에 문제가 없을 수도 있습니다.
저는 이것의 전체적인 예를 들어 이 게시물을 편집할 시간을 찾도록 노력할 것입니다.
이 질문은 제가 한 게시물에 몇 가지 마샬/언마샬 솔루션을 수집한 또 다른 질문과 약간 중복되는 것 같습니다.JAXB로 동적 태그명을 확인하실 수 있습니다.
간단히 말해서:
- 에 대한 컨테이너 :
@xmlAnyElement
ㅠㅠ -
XmlAdapter
과로수다할다할 수 있습니다.@XmlJavaTypeAdapter
와 Map
xml-apis-1.0을 사용하는 경우 다음을 직렬화 및 역직렬화할 수 있습니다.
<?xml version="1.0" encoding="UTF-8"?>
<root>
<map>
<key>value</key>
<key2>value2</key2>
</map>
</root>
다음 코드 사용:
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@XmlRootElement
class Root {
public XmlRawData map;
}
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Root root = (Root) unmarshaller.unmarshal(new File("src/input.xml"));
System.out.println(root.map.getAsMap());
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
class XmlRawData {
@XmlAnyElement
public List<Element> elements;
public void setFromMap(Map<String, String> values) {
Document document;
try {
document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
}
for (Entry<String, String> entry : values.entrySet()) {
Element mapElement = document.createElement(entry.getKey());
mapElement.appendChild(document.createTextNode(entry.getValue()));
elements.add(mapElement);
}
}
public Map<String, String> getAsMap() {
Map<String, String> map = new HashMap<String, String>();
for (Element element : elements) {
if (element.getNodeType() == Node.ELEMENT_NODE) {
map.put(element.getLocalName(), element.getFirstChild().getNodeValue());
}
}
return map;
}
}
잭슨은 이것을 즉시 지원할 XmlMapper를 가지고 있습니다. 코드를 전혀 쓸 필요가 없습니다.
여기 멋진 튜토리얼이 있습니다. https://www.baeldung.com/jackson-xml-serialization-and-deserialization
메이븐 종속성:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.8</version>
</dependency>
를 Map
xml:xml 파일:
Map<String, String> map = new HashMap<>();
map.put("SomeKey", "someValue");
XmlMapper mapper = new XmlMapper();
String xml = mapper.writeValueAsString(map);
줄께요
<HashMap><SomeKey>someValue</SomeKey></HashMap>
를 은 은 을 만들어 루트 요소를 맞춤화할 수 .HashMap
@JacksonXmlRootElement(localName = "MyRootElement")
public class XmlHashMap<K, V> extends HashMap<K, V>
{
}
그래서 이제
Map<String, String> map = new XmlHashMap<>();
map.put("SomeKey", "someValue");
XmlMapper mapper = new XmlMapper();
String xml = mapper.writeValueAsString(map);
줄께요
<MyRootElement><SomeKey>someValue</SomeKey></MyRootElement>
은 에 대해서만 했습니다.marshalling
둘다 ㅇㅇmarshalling
그리고.unmarshalling
와 함께Map<String,Object>
import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.annotation.XmlAnyElement;
import jakarta.xml.bind.annotation.adapters.XmlAdapter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.xml.namespace.QName;
import lombok.Getter;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class MoxyMapAdapter extends XmlAdapter<MapWrapper, Map<String, Object>> {
@Override
public Map<String, Object> unmarshal(MapWrapper value) {
final Map<String, Object> extensions = new HashMap<>();
//Loop across all elements within value
for (Object obj : value.getElements()) {
Element element = (Element) obj;
final NodeList children = element.getChildNodes();
if (children.getLength() == 1) {
extensions.put(element.getNodeName(), element.getTextContent());
} else {
List<Object> child = new ArrayList<>();
for (int i = 0; i < children.getLength(); i++) {
final Node n = children.item(i);
if (n.getNodeType() == Node.ELEMENT_NODE) {
MapWrapper wrapper = new MapWrapper();
List childElements = new ArrayList();
childElements.add(n);
wrapper.elements = childElements;
child.add(unmarshal(wrapper));
}
}
extensions.put(element.getNodeName(), child);
}
}
return extensions;
}
@Override
public MapWrapper marshal(Map<String, Object> extensions) throws Exception {
if (extensions == null) {
return null;
}
MapWrapper wrapper = new MapWrapper();
List elements = new ArrayList();
//Loop through the Extensions MAP
for (Map.Entry<String, Object> property : extensions.entrySet()) {
//If the Value type is MAP then recurse through the loop
if (property.getValue() instanceof Map) {
elements
.add(new JAXBElement<MapWrapper>(new QName(namespaceURI, localPart, prefix), MapWrapper.class, marshal((Map) property.getValue())));
} else if (property.getValue() instanceof String) {
// If the Value type is String then directly create JAXBElement
elements.add(new JAXBElement<String>(new QName(namespaceURI, localPart, prefix), String.class, property.getValue().toString()));
} else if (property.getValue() instanceof ArrayList) {
//If the Value type is ArrayList then it contains Duplicate key values so Loop through it
for (Object dupItems : (ArrayList<String>) property.getValue()) {
if (dupItems instanceof Map) {
elements.add(new JAXBElement<MapWrapper>(new QName(namespaceURI, localPart, prefix), MapWrapper.class, marshal((Map) dupItems)));
} else {
elements.add(new JAXBElement<String>(new QName(namespaceURI, localPart, prefix), String.class, dupItems.toString()));
}
}
}
}
wrapper.elements = elements;
return wrapper;
}
}
class MapWrapper {
@Getter
@XmlAnyElement
List elements;
}
가장 쉬운 해결책을 찾았습니다.
@XmlElement(name="attribute")
public String[] getAttributes(){
return attributes.keySet().toArray(new String[1]);
}
}
이제 다음과 같이 xml 출력을 생성합니다.
<attribute>key1<attribute>
...
<attribute>keyN<attribute>
언급URL : https://stackoverflow.com/questions/3941479/jaxb-how-to-marshall-map-into-keyvalue-key
'programing' 카테고리의 다른 글
팬더 데이터 프레임에서 두 열의 값을 단일 열로 병합합니다. (0) | 2023.09.14 |
---|---|
(WP-CLI) Wordpress-Tests_Lib 파일이 생성되지 않음 (0) | 2023.09.14 |
어린이를 조롱하는 구성 요소 - 각도 2 (0) | 2023.09.14 |
SQL - Union of Selects inside Where...인절 (0) | 2023.09.14 |
MySQL regex에서 캡처 그룹을 어떻게 참조합니까? (0) | 2023.09.14 |