将具有相同 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 中完成,因为它不适合这些类型的修改。相反,你应该:
- 使用 XLST 将您的 XML 转换为正确的对象表示形式
或
- 创建一个代表您当前 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>
我有以下 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 中完成,因为它不适合这些类型的修改。相反,你应该:
- 使用 XLST 将您的 XML 转换为正确的对象表示形式
或
- 创建一个代表您当前 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>