У меня есть xsd say 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.
Теперь, как мне получить все значения листового узла (операция, имя, workName) в общем виде без использования геттеров из объекта запроса, и каждый из которых затем я могу поместить в некоторую коллекцию, скажем, List. Я слышал, что DOM используется для подобных вещей, но мне нужно использовать JAXB для того же.
(Без использования геттеров из объекта запроса, например String opertaion = request.getOperation();
или String name = request.getWork().getWorkModule().getName();
)
--РЕДАКТИРОВАТЬ--
Может ли кто-нибудь помочь мне найти оптимальное решение для этого. Дайте мне знать, если формулировка проблемы не ясна.
--EDIT-- С помощью 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()));
}