如何使用Moxy将xml属性解析为键值

时间:2018-02-16 21:51:58

标签: jaxb eclipselink pojo moxy

我正在尝试使用MOXy解析下面的xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dml>
<dml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<content>
<entry>
      <namespace>
        <meta property="abc" content="abcd" />
        <meta property="xyz" content="xyzd" />
      </namespace>
    </entry>
    <entry>
      <namespace>
        <meta property="abc" content="pqr" />
        <meta property="xyz" content="xyzd" />
        <meta property="lmn" content="qwert" />
      </namespace>
    </entry>
</content>
</dml>

我想解析属性&#39;属性&#39;和&#39;内容&#39;元素&#39; meta&#39;作为关键值对。

我使用了以下链接,但没有运气。元图对我来说是空的。 http://blog.bdoughan.com/2013/06/moxys-xmlvariablenode-using-maps-key-as.html

这是我的课程。

  public static void parseDml(String dmlXmlFile) throws Exception {  

    DMLData dmlData = null;
    try 
    {
      JAXBContext jaxbContext = JAXBContext.newInstance(DMLData.class);
      unmarshaller = jaxbContext.createUnmarshaller();

      dmlData = (DMLData) unmarshaller.unmarshal(new File(dmlXmlFile));

      Marshaller marshaller = jaxbContext.createMarshaller();
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
      marshaller.marshal(dmlData, System.out);
    }
    catch (Exception e)
    {
      throw new Exception("Error while unmarshalling dml XML : " + e);
    }

  }

DMLData.java

@Getter
@NoArgsConstructor
@XmlRootElement(name = "dml")
@XmlAccessorType(XmlAccessType.FIELD)
public class DMLData
{

  @XmlPath("content/entry")
  private List<Entry> entry;


}

Entry.java

@XmlRootElement(name = "entry")
@Getter
@XmlAccessorType(XmlAccessType.FIELD)
public class Entry
{

  @XmlPath("namespace/meta")
  @XmlJavaTypeAdapter(MapAdapter.class)
  private Map<String, String> map = new HashMap<String, String>();

}

Meta.java

@XmlRootElement(name = "boeXmlMeta")
@Getter
@XmlAccessorType(XmlAccessType.FIELD)
public class Meta
{

  private Map<String, String> boeXmlMeta = new HashMap<String, String>();

  @XmlPath("@property")
  private String property;

  @XmlPath("@content")
  private String content;

  public void setProperty(String model)
  {
    this.property = property;
  }

  public void setContent(String content)
  {
    this.content = content;
  } 
}

MapAdapter.java

public class MapAdapter extends XmlAdapter<List<Meta>,HashMap<String,String>> {


  @Override
  public ArrayList<Meta> marshal(HashMap<String, String> map) throws Exception {
    ArrayList<Meta> list = new ArrayList<Meta>();
      for(Entry<String, String> entry : map.entrySet()) {
          Meta Meta = new Meta();
          Meta.setProperty(entry.getKey());
          Meta.setContent(entry.getValue());
          list.add(Meta);
      }
      return list;
  }

  @Override
  public HashMap<String, String> unmarshal(List<Meta> MetaList) throws Exception {
      HashMap<String, String> map = new HashMap<String, String>(MetaList.size());
      for(Meta Meta : MetaList)
      {
        map.put(Meta.getProperty() ,Meta.getContent());
      }
      return map;
  }

}

这是我得到的输出:

<?xml version="1.0" encoding="UTF-8"?>
<dml>
   <content>
      <entry/>
      <entry/>
   </content>
</dml>

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

我认为不需要XmlPath,好的XmlElementXmlAttribute会很好。

Entry.java:

@XmlElement(name = "namespace")
@XmlJavaTypeAdapter(MapAdapter.class)
private Map<String, String> map = new HashMap<>();

Meta.java:

@XmlAttribute(name = "property")
private String property;

@XmlAttribute(name = "content")
private String content;

MapAdapter.java:

public class MapAdapter extends XmlAdapter<Namespace, Map<String, String>> {

    @XmlRootElement(name = "meta")
    @XmlAccessorType(XmlAccessType.FIELD)
    public static class Namespace {

        @XmlElement(name = "meta")
        private List<Meta> metas;

        public Namespace() {
        }

        public Namespace(List<Meta> list) {
            metas = list;
        }

        public List<Meta> getMetas() {
            return metas;
        }

    }

    @Override
    public Namespace marshal(Map<String, String> map) throws Exception {
        List<Meta> list = new ArrayList<>();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            Meta meta = new Meta();
            meta.setProperty(entry.getKey());
            meta.setContent(entry.getValue());
            list.add(meta);
        }
        return new Namespace(list);
    }

    @Override
    public Map<String, String> unmarshal(Namespace metaList) throws Exception {
        Map<String, String> map = new HashMap<>();
        for (Meta meta : metaList.metas) {
            map.put(meta.getProperty(), meta.getContent());
        }
        return map;
    }

}

我在这里添加了另一个帮助类来描述Namespace