【问题标题】:How to set keys of a HashMap as the tags in XML file?如何将 HashMap 的键设置为 XML 文件中的标签?
【发布时间】:2013-07-03 22:22:48
【问题描述】:

原问题: 所以我有一个很大的 Excel 表,上面有一堆带有值的标签,认为 Party_Name 是标签,“IBM”是那个特定单元格中的值。我已将它们全部读入 HashMap,键是标签,值是单元格的值(均为字符串类型)。问题是,我希望能够将每个标记绑定为一个 XML 标记,以便当我将它指向一个派对的特定路径时它会显示在 Web 浏览器中。是否可以动态设置这些 xml 元素,因为静态制作 100 多个标签很痛苦?

更新:我已经能够将 Excel 工作表的所有标签/值读取到 HashMap 中,然后将其转换为 AdaptedMap,该 AdaptedMap 允许动态显示 hashpmap 中每个条目的值/键。就是丑,格式目前是这样的

<Party>
  <entry>
    <key> PARTY_NAME> </key>
    <value> IBM </value>
  </entry>
  <entry>
    <key> id </key>
    <value> 123456 </value>
  ...etc

我想把它格式化,让它更像这样

<Party>
  <entry>
     <PARTY_NAME> IBM </PARTY_NAME>
  </entry>
  <entry>
     <id> 123456 </id>
  etc...

甚至去掉“条目”标签。有人知道这样做的方法吗?这是我的相关代码:

package pojo;

import java.util.HashMap;
import java.util.Map;
import java.io.File;
import javax.xml.bind.*;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

import org.eclipse.persistence.jaxb.MarshallerProperties;

@XmlRootElement(name="Party")
@XmlAccessorType(XmlAccessType.FIELD)
public class Party {

HashMap <String,String> partyInfo = new HashMap<String,String>();

public HashMap<String,String> getPartyInfo() throws Exception
{
    MapAdapter adapter = new MapAdapter();
    adapter.marshal(partyInfo);
    return partyInfo;
}

这是我从上一个涉及相同问题的问题中学习的课程(页面底部的链接)

package pojo;
import java.util.*;
import java.util.Map.Entry;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.eclipse.persistence.oxm.annotations.XmlVariableNode;

public class MapAdapter extends XmlAdapter<MapAdapter.AdaptedMap, Map<String, String>>{

public static class AdaptedMap
{
    @XmlVariableNode("key")
    List<AdaptedEntry> entries = new ArrayList<AdaptedEntry>();
}

public static class AdaptedEntry
{
    @XmlTransient
    public String key;

    @XmlValue
    public String value;
}
@Override
public AdaptedMap marshal(Map<String,String> map) throws Exception
{
    AdaptedMap adaptedMap = new AdaptedMap();
    for(Entry<String, String> entry : map.entrySet())
    {
        AdaptedEntry adaptedEntry = new AdaptedEntry();
        adaptedEntry.key= entry.getKey();
        adaptedEntry.value=entry.getValue();
        adaptedMap.entries.add(adaptedEntry);           
    }
    return adaptedMap;
}

注意:我是新来的,所以在跟进上一个问题时我不确定礼仪。无论如何,这是原始问题的链接

How to set xml annotations dynamically?

注 2:我对 xml 注释很不满意,所以如果有什么明显错误,那是因为我一直在复制其中的一些内容,而不是从逻辑上理解。我试过阅读上面的 javadocs,但并不完全清楚,可能是因为我缺乏 xml 经验

【问题讨论】:

    标签: java xml excel jaxb moxy


    【解决方案1】:

    以下是更正后的示例。

    Java 模型(方)

    @XmlJavaTypeAdapter 注解用于引用XmlAdapter 实现类。我们还将使用 MOXy 的 @XmlPath 注释来消除所需的父元素(请参阅:http://blog.bdoughan.com/2010/07/xpath-based-mapping.html)。

    package pojo;
    
    import java.util.HashMap;
    import javax.xml.bind.annotation.*;
    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    import org.eclipse.persistence.oxm.annotations.XmlPath;
    
    @XmlRootElement(name = "Party")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Party {
    
        @XmlPath(".")
        @XmlJavaTypeAdapter(MapAdapter.class)
        HashMap<String, String> partyInfo = new HashMap<String, String>();
    
    }
    

    XmlAdapter (MapAdapter)

    XmlAdapter 允许您将对象转换为不同的类型以进行编组/解组。在本例中,我们将使用它将 Map 转换为能够利用 MOXy 的 @XmlVariableNode 扩展的对象结构(请参阅:http://blog.bdoughan.com/2013/06/moxys-xmlvariablenode-using-maps-key-as.html)。 @XmlVariableNode 使您能够从对象上的字段/属性派生节点名称。

    package pojo;
    
    import java.util.*;
    import java.util.Map.Entry;
    import javax.xml.bind.annotation.*;
    import javax.xml.bind.annotation.adapters.XmlAdapter;
    import org.eclipse.persistence.oxm.annotations.XmlVariableNode;
    
    public class MapAdapter extends
            XmlAdapter<MapAdapter.AdaptedMap, Map<String, String>> {
    
        public static class AdaptedMap {
            @XmlVariableNode("key")
            List<AdaptedEntry> entries = new ArrayList<AdaptedEntry>();
        }
    
        public static class AdaptedEntry {
            @XmlTransient
            public String key;
    
            @XmlValue
            public String value;
        }
    
        @Override
        public AdaptedMap marshal(Map<String, String> map) throws Exception {
            AdaptedMap adaptedMap = new AdaptedMap();
            for (Entry<String, String> entry : map.entrySet()) {
                AdaptedEntry adaptedEntry = new AdaptedEntry();
                adaptedEntry.key = entry.getKey();
                adaptedEntry.value = entry.getValue();
                adaptedMap.entries.add(adaptedEntry);
            }
            return adaptedMap;
        }
    
        @Override
        public Map<String, String> unmarshal(AdaptedMap adaptedMap)
                throws Exception {
            List<AdaptedEntry> adaptedEntries = adaptedMap.entries;
            Map<String, String> map = new HashMap<String, String>(
                    adaptedEntries.size());
            for (AdaptedEntry adaptedEntry : adaptedEntries) {
                map.put(adaptedEntry.key, adaptedEntry.value);
            }
            return map;
        }
    
    }
    

    jaxb.properties

    要将 MOXy 指定为您的 JAXB 提供程序,您需要在与域模型相同的包中包含一个名为 jaxb.properties 的文件,并使用以下条目(请参阅:http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html)。

    javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
    

    演示

    package pojo;
    
    import java.io.File;
    import javax.xml.bind.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(Party.class);
    
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            File xml = new File("src/pojo/input.xml");
            Party party = (Party) unmarshaller.unmarshal(xml);
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(party, System.out);
        }
    
    }
    

    input.xml/Output

    下面是运行演示代码的输入和输出。

    <?xml version="1.0" encoding="UTF-8"?>
    <Party>
       <id> 123456 </id>
       <PARTY_NAME> IBM </PARTY_NAME>
    </Party>
    

    更多信息

    【讨论】:

    • 您的示例效果很好,我对此只有一个问题。我也在使用杰克逊库,看起来杰克逊没有使用 XmlJavaAdapter 注释,输出中简单地缺少派对元素。如果我注释掉 XmlJavaAdapter 注释,则该对象存在但不是正确的形式。你知道为什么会这样吗?
    猜你喜欢
    • 2013-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多