【问题标题】:JAXB Unmarshalling having same XML elements and same attribute names but different attribute values into different Java objects将具有相同 XML 元素和相同属性名称但不同属性值的 JAXB 解组到不同的 Java 对象中
【发布时间】:2021-10-08 08:47:19
【问题描述】:

我有以下 xml,它具有相同的 XML 元素 <child/> 以及相同的属性名称“action”重复多次(可能在此 xml 中重复 1000 次)-我想使用 JAXB 解组此 xml(注释或客户适配器),根据属性“action”的值转换为多个 Java 对象。

例如对于所有“action”属性值“Unchanged”,我可以映射到 List 不变列表对象,对于所有“action”属性值“New”,我想映射到 List newList 等等。我们可以这样做吗?如何做?

<parent>
   <child name="John1"  reason="12" action="Unchanged" />
   <child name="John2"  reason="12" action="Unchanged" />
   <child name="John3"  reason="12" action="New" />
   <child name="John4"  reason="12" action="New" />
   <child name="John5"  reason="12" action="Delete" />
   <child name="John6"  reason="12" action="Delete" />
   <child name="John8"  reason="12" action="Unchanged" />
   <child name="John9"  reason="12" action="Delete" />
   <child name="John10" reason="12" action="New" />
</parent>

【问题讨论】:

  • 您是否查看过@XmlNamedObjectGraphs@XmlNamedObjectGraph 您可以定义不同的proporder 属性并在解组期间添加它们?不确定这是否是您正在寻找的,但请尝试一下。

标签: java xml xml-parsing jaxb


【解决方案1】:

我再次查看了这个问题并理解了您的要求,以下是您提供的 XML 的完美代码。如果您想进行一些修改,您可以在Child.cass

中进行相应的修改

父类:

@XmlRootElement(name = "parent")
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class Parent {
    @XmlElement(name = "child")
    List<Child> child;
}

子类:

@Data
@XmlAccessorType(XmlAccessType.NONE)
public class Child {
    @XmlAttribute
    private String name;

    @XmlAttribute
    private String reason;

    @XmlAttribute
    private String action;

    @XmlAttribute
    List<String> unchangedList;

    @XmlAttribute
    List<String> newList;

    @XmlAttribute
    List<String> deleteList;

    private void afterUnmarshal(Unmarshaller m, Object parent) {
        if (action.equals("Unchanged")) {
            unchangedList = new ArrayList<>();
            unchangedList.add(action);
        } else if (action.equals("New")) {
            newList = new ArrayList<>();
            newList.add(action);
        } else if (action.equals("Delete")) {
            deleteList = new ArrayList<>();
            deleteList.add(action);
        }
        action = null;
    }
}

JaxBMain.class:

public class JaxBMain {

    public static void main(String[] args) throws JAXBException, XMLStreamException {
        final InputStream inputStream = Unmarshalling.class.getClassLoader().getResourceAsStream("action.xml");
        final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
        final Unmarshaller unmarshaller = JAXBContext.newInstance(Parent.class).createUnmarshaller();
        final Parent parent = unmarshaller.unmarshal(xmlStreamReader, Parent.class).getValue();
        System.out.println(parent.toString());

        Marshaller marshaller = JAXBContext.newInstance(Parent.class).createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.marshal(parent, System.out);
    }
}

以下是您将获得的输出:

Parent(child=[Child(name=John1, reason=12, action=null, unchangedList=[Unchanged], newList=null, deleteList=null), Child(name=John2, reason=12, action=null, unchangedList=[Unchanged], newList=null, deleteList=null), Child(name=John3, reason=12, action=null, unchangedList=null, newList=[New], deleteList=null), Child(name=John4, reason=12, action=null, unchangedList=null, newList=[New], deleteList=null), Child(name=John5, reason=12, action=null, unchangedList=null, newList=null, deleteList=[Delete]), Child(name=John6, reason=12, action=null, unchangedList=null, newList=null, deleteList=[Delete]), Child(name=John8, reason=12, action=null, unchangedList=[Unchanged], newList=null, deleteList=null), Child(name=John9, reason=12, action=null, unchangedList=null, newList=null, deleteList=[Delete]), Child(name=John10, reason=12, action=null, unchangedList=null, newList=[New], deleteList=null)])
<parent>
   <child name="John1" reason="12" unchangedList="Unchanged"/>
   <child name="John2" reason="12" unchangedList="Unchanged"/>
   <child name="John3" reason="12" newList="New"/>
   <child name="John4" reason="12" newList="New"/>
   <child name="John5" reason="12" deleteList="Delete"/>
   <child name="John6" reason="12" deleteList="Delete"/>
   <child name="John8" reason="12" unchangedList="Unchanged"/>
   <child name="John9" reason="12" deleteList="Delete"/>
   <child name="John10" reason="12" newList="New"/>
</parent>

【讨论】:

    【解决方案2】:
    public class child { 
        public String name;
        public int reason;
        public String action;
    }
    
    public class parent { 
        public List<child> child;
    }
    

    以这种方式创建你的类,一旦你有列表,然后使用java8过滤列表方法来获取具有相同值的数据。

    【讨论】:

      【解决方案3】:

      所以根据我的理解,JAXB 是将 XML 映射到匹配的 Java 对象,反之亦然。因此,您尝试的操作不应该在 JAXB 中完成,因为它不适合此类修改。相反,您应该:

      1. 使用 XLST 将您的 XML 转换为正确的对象表示

      1. 创建一个代表当前 XML 的对象,然后在 java 中对其进行处理。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多