jaxb将多个xml元素封送和解封到一个类中并进行反向

zbwhf8kr  于 2021-07-03  发布在  Java
关注(0)|答案(2)|浏览(328)

我正在尝试将以下“attrname”和“attrtype”xml元素封送和解封到一个类中(目前,我单独读取这些值,并在java中解组后构造对象。)

  1. <wrapper>
  2. <someOtherElement>xxx</someOtherElement>
  3. <attrName ref="a">xxx</attrName>
  4. <attrName ref="b">xxx</attrName>
  5. <attrName ref="c">xxx</attrName>
  6. <attrType attrRef="a">xxx</attrType>
  7. <attrType attrRef="b">xxx</attrType>
  8. <someOtherElement>xxx</someOtherElement>
  9. </wrapper>

“ref”xml属性用于标识属性并作为“attrtype”xml元素的引用。但是“attrtype”xml元素是可选的,不能存在。没有“attrname”xml元素就不能有“attrtype”xml元素。
我需要生成类的“attribute”对象列表:

  1. package example;
  2. public class Attribute {
  3. private String name;
  4. private String ref;
  5. private String type;
  6. public String getName() {
  7. return name;
  8. }
  9. public void setName(String name) {
  10. this.name= name;
  11. }
  12. public String getRef() {
  13. return ref;
  14. }
  15. public void setRef(String ref) {
  16. this.ref= ref;
  17. }
  18. public String getType() {
  19. return type;
  20. }
  21. public void setType(String type) {
  22. this.type= type;
  23. }
  24. }

我已经发现了以下相关问题。但这无助于我找到解决问题的办法。问题是找到所有相关的属性名和类型来构造java对象。
如果有任何正确的建议,我将不胜感激。如果我没有解释任何令人满意的事情,请不要犹豫,因为英语不是我的母语。
ps:我知道我可以使用不同的xml结构,很容易解决问题。但这对我来说是不可能的。

3j86kqsm

3j86kqsm1#

您的xml文件不遵循任何模式,因此只能依赖其根元素名称和格式良好的事实。下面将其Map到通用 Package 器对象,然后对其进行处理以生成属性对象列表:

  1. public class JAXBAttribute {
  2. public static void main(String[] args) throws JAXBException {
  3. JAXBContext context = JAXBContext.newInstance(new Class[] {Wrapper.class});
  4. Wrapper wrapper = (Wrapper)context.createUnmarshaller().unmarshal(Thread.currentThread().getContextClassLoader().getResourceAsStream("wrapper.xml"));
  5. final Map<String,String> attributeTypeMap = new HashMap<String,String>();
  6. for(final AttributeTypeMapEntry entry : wrapper.getEntryList()) {
  7. attributeTypeMap.put(entry.getKey(), entry.getValue());
  8. }
  9. for(final Attribute a : wrapper.getAttributeObjectList()) {
  10. a.setType(attributeTypeMap.get(a.getRef()));
  11. }
  12. System.out.println(wrapper.getAttributeObjectList());
  13. }
  14. }
  15. @XmlRootElement(name="wrapper")
  16. @XmlAccessorType(XmlAccessType.NONE)
  17. class Wrapper {
  18. @XmlElement(name="attrName")
  19. private List<Attribute> attributeObjectList;
  20. @XmlElement(name="attrType")
  21. private List<AttributeTypeMapEntry> entryList;
  22. public List<Attribute> getAttributeObjectList() {
  23. return attributeObjectList;
  24. }
  25. public List<AttributeTypeMapEntry> getEntryList() {
  26. return entryList;
  27. }
  28. }
  29. @XmlAccessorType(XmlAccessType.NONE) // Only annotated fields will be mapped
  30. class AttributeTypeMapEntry {
  31. @XmlAttribute(name="attrRef")
  32. private String key;
  33. @XmlValue
  34. private String value;
  35. public String getKey() {
  36. return key;
  37. }
  38. public void setKey(String key) {
  39. this.key = key;
  40. }
  41. public String getValue() {
  42. return value;
  43. }
  44. public void setValue(String value) {
  45. this.value = value;
  46. }
  47. @Override
  48. public String toString() {
  49. return "AttributeTypeMapEntry [key=" + key + ", value=" + value + "]";
  50. }
  51. }
  52. @XmlAccessorType(XmlAccessType.NONE) // Only annotated fields will be mapped
  53. class Attribute {
  54. @XmlValue
  55. private String name;
  56. private String type;
  57. @XmlAttribute(name="ref")
  58. private String ref;
  59. public String getName() {
  60. return name;
  61. }
  62. public void setName(String name) {
  63. this.name= name;
  64. }
  65. public String getRef() {
  66. return ref;
  67. }
  68. public void setRef(String ref) {
  69. this.ref= ref;
  70. }
  71. public String getType() {
  72. return type;
  73. }
  74. public void setType(String type) {
  75. this.type= type;
  76. }
  77. @Override
  78. public String toString() {
  79. return "Attribute [name=" + name + ", type=" + type + ", ref=" + ref + "]";
  80. }
  81. }
展开查看全部
uelo1irk

uelo1irk2#

这是同一任务的另一个解决方案。其思想是将初始文档转换为直接Mapxml形式,同时解析所有引用,然后将生成的xmlMap到java对象。
数据的xslt是:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  3. <xsl:output method="xml" indent="yes"/>
  4. <xsl:template match="/wrapper">
  5. <xsl:variable name="root" select="."/>
  6. <xsl:copy>
  7. <xsl:for-each select="attrName">
  8. <xsl:variable name="ref" select="@ref"></xsl:variable>
  9. <attribute>
  10. <name><xsl:value-of select="text()"/></name>
  11. <ref><xsl:value-of select="$ref"/></ref>
  12. <type><xsl:value-of select="$root/attrType[@attrRef=$ref]/text()"/></type>
  13. </attribute>
  14. </xsl:for-each>
  15. </xsl:copy>
  16. </xsl:template>
  17. <xsl:template match="text()"/>
  18. </xsl:stylesheet>

直接Mapxml如下所示:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <wrapper>
  3. <attribute>
  4. <name>xxx</name>
  5. <ref>a</ref>
  6. <type>xxx</type>
  7. </attribute>
  8. <attribute>
  9. <name>xxx</name>
  10. <ref>b</ref>
  11. <type>xxx</type>
  12. </attribute>
  13. <attribute>
  14. <name>xxx</name>
  15. <ref>c</ref>
  16. <type/>
  17. </attribute>
  18. </wrapper>

带有注解的代码如下:

  1. public class JAXBAttribute {
  2. public static void main(String[] args) throws Exception {
  3. // Transform initial XML resolving all references, resulting in an straight-to-map XML
  4. final Transformer t = TransformerFactory.newInstance().newTransformer(
  5. new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream("wrapper.xsl")));
  6. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  7. t.transform(
  8. new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream("wrapper.xml")),
  9. new StreamResult(baos));
  10. // Create Java objects from a straight-to-map XML
  11. JAXBContext context = JAXBContext.newInstance(new Class[] {Wrapper.class});
  12. Wrapper wrapper = (Wrapper)context.createUnmarshaller().unmarshal(new ByteArrayInputStream(baos.toByteArray()));
  13. //
  14. System.out.println(wrapper.getAttributeObjectList());
  15. }
  16. }
  17. @XmlRootElement(name="wrapper")
  18. @XmlAccessorType(XmlAccessType.FIELD)
  19. class Wrapper {
  20. @XmlElement(name="attribute")
  21. private List<Attribute> attributeObjectList;
  22. public List<Attribute> getAttributeObjectList() {
  23. return attributeObjectList;
  24. }
  25. }
  26. @XmlAccessorType(XmlAccessType.FIELD)
  27. class Attribute {
  28. private String name;
  29. private String type;
  30. private String ref;
  31. public String getName() {
  32. return name;
  33. }
  34. public void setName(String name) {
  35. this.name= name;
  36. }
  37. public String getRef() {
  38. return ref;
  39. }
  40. public void setRef(String ref) {
  41. this.ref= ref;
  42. }
  43. public String getType() {
  44. return type;
  45. }
  46. public void setType(String type) {
  47. this.type= type;
  48. }
  49. @Override
  50. public String toString() {
  51. return "Attribute [name=" + name + ", type=" + type + ", ref=" + ref + "]";
  52. }
  53. }

注意本例中的所有文件都保存在类路径根目录中。

展开查看全部

相关问题