将具有相同 XML 元素和相同属性名称但不同属性值的 JAXB 解组到不同的 Java 对象中

JAXB Unmarshalling having same XML elements and same attribute names but different attribute values into different Java objects

我有以下 xml 具有相同的 XML 元素 <child/> 并且相同的属性名称“action”重复了多次(在此 [=19 中可能重复了 1000 次) =]) - 我想使用 JAXB(注释或客户适配器)将此 xml 解组为多个 Java 基于属性“action”的值的对象。

例如对于所有“action”属性值“Unchanged”,我可以映射到 List unchangedList 对象,对于所有“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>
public class child { 
    public String name;
    public int reason;
    public String action;
}

public class parent { 
    public List<child> child;
}

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

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

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

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

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

中进行相应的修改

Parent.class:

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

Child.class:

@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>