【发布时间】:2013-12-20 13:09:30
【问题描述】:
我有一个 xsd 说 request.xsd 和相应的 jaxb 生成的类。现在我得到了一个 xml 文件 request.xml,我可以解组并创建“请求”对象。
我在 xml 中有很多元素标签,其中一些标签可以多次使用。我需要创建一个应该包含所有叶节点值的 java.util.List。
例如:
下面是我的 request.xml :
<Request>
<Operation>manual</Operation>
<Work>
<WorkModule>
<Name>AXN</Name>
</WorkModule>
</Work>
<Identifier>
<WorkStatus>
<WorkName>CCH</WorkName>
</WorkStatus>
<WorkStatus>
<WorkName>TMH</WorkName>
</WorkStatus>
</Identifier>
</Request>
下面是我的 JAXB 生成的请求类。同样每个xml元素对应的还有其他类:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"Operation",
"Work",
"Identifier"
})
@XmlRootElement(name = "Request", namespace = "http://www.sprts.com/clm/nso/mahsgd")
public class Request{
@XmlElement(name = "Operation", required = true)
protected Operation operation;
@XmlElement(name = "Work", required = true)
protected Work work;
@XmlElement(name = "Identifier", required = true)
protected Identifier identifier;
\\ getters and setters
}
因此,使用 JAXB 我可以获得未编组的请求对象,该对象具有 xml 文件中的所有值。
现在我如何在不使用请求对象的 getter 的情况下以通用方式获取所有叶节点值(操作、名称、工作名称),然后我可以将其中的每一个放入某个集合中,比如说 List。我听说 DOM 被用来做类似的事情,但我需要使用 JAXB。
(不使用来自请求对象的getter,例如
String opertaion = request.getOperation(); 或 String name = request.getWork().getWorkModule().getName();)
--编辑--
谁能帮我找到一个最佳解决方案。如果问题陈述不清楚,请告诉我。
--编辑-- 在 Doughan & Alexandros 的帮助下,周围的一些人也能做到这一点。不确定解决方法(将 JAXB 对象转换为 DOM 对象到 InputSource)是否是最佳解决方案。下面是工作代码。
JAXBContext jc = JAXBContext.newInstance(JAXBObject.class);
// Create the Document
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.newDocument();
// Marshal the Object to a Document
Marshaller marshaller = jc.createMarshaller();
marshaller.marshal(jaxbObject, document);
XPathFactory xpf = XPathFactory.newInstance();
XPath xp = xpf.newXPath();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Source xmlSource = new DOMSource(document);
Result outputTarget = new StreamResult(outputStream);
TransformerFactory.newInstance().newTransformer().transform(xmlSource,outputTarget);
InputStream is = new ByteArrayInputStream(outputStream.toByteArray());
InputSource source = new InputSource(is);
NodeList leafNodeObjects = (NodeList) xp.evaluate("//*[not(*)]", source, XPathConstants.NODESET);
for(int x=0; x<leafNodeObjects.getLength(); x++) {
System.out.print("nodeElement = ");
System.out.print(leafNodeObjects.item(x).getNodeName());
System.out.print(" and node value = ");
System.out.println(leafNodeObjects.item(x).getTextContent());
inputDtos.add(new InputDto(leafNodeObjects.item(x).getNodeName(),
leafNodeObjects.item(x).getTextContent()));
}
【问题讨论】:
-
您手头有很棒的对象,其中每个属性/方法都有一定的意义。你想要实现什么,你想要一种通用的方式并考虑用 DOM 之类的东西来替换你的类型化数据结构?然而,显而易见但不好的答案是“使用反射”。但我敦促您解释您想要实现的目标,以便我们提出更好的解决方案。
-
使用来自请求对象的简单 getter,我可以创建一个工作正常的列表。我在 xml 中有大约 150 个字段,因此手动映射每个 xml 元素仍然可以,但我希望这个数字将来会增长。在这种情况下,我必须再次验证从 xml 中添加或删除的字段,并且必须完成相应的映射才能放入我想要避免的集合中。
标签: java xml-parsing jaxb unmarshalling xmlnode