I wanted read a xml file from azure blob storage and write to another xml file to azure blob storage. I am using spring cloud to integrate with azure blob storage. I tried writing with JAXB as follows which works well
private void launchJaxb() {
AtomicInteger counter = new AtomicInteger(0);
List<Verify> verifications = new ArrayList<>();
Resource readResource = resourceLoader.getResource(String.format(BLOB_RESOURCE_PATTERN, containerName, "9898.xml"));
Resource writeResource = resourceLoader.getResource(String.format(BLOB_RESOURCE_PATTERN, containerName, "9898-out.xml"));
try {
XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
XMLEventReader xmlEventReader = xmlInputFactory.createXMLEventReader(readResource.getInputStream());
JAXBContext readJc = JAXBContext.newInstance(Verify.class);
Unmarshaller unmarshaller = readJc.createUnmarshaller();
BufferedOutputStream bos = new BufferedOutputStream(((WritableResource) writeResource).getOutputStream());
JAXBContext writeJc = JAXBContext.newInstance(Verify.class);
Marshaller marshaller = writeJc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
var rootElements = createRootElements();
while (xmlEventReader.hasNext()) {
if (xmlEventReader.peek().isStartElement() && xmlEventReader.peek().asStartElement().getName().getLocalPart().equals("account")) {
Verification verification = (Verification) unmarshaller.unmarshal(xmlEventReader);
counter.incrementAndGet();
verifications.add(verification);
if (verifications.size() == 100) {
var accountValidationResponses = process.verify(verifications);
for (Report report : accountValidationResponses) {
rootElements.getReport().add(report);
}
verifications = new ArrayList<>();
}
}
xmlEventReader.nextEvent();
}
rootElements.setNumberOfEvents(BigInteger.valueOf(counter.get()));
marshaller.marshal(rootElements, bos);
bos.close();
log.info("Total processed verifications {}", counter.get());
} catch (IOException | XMLStreamException | JAXBException e) {
throw new RuntimeException(e);
}
}
Using above code i was able to write xml file blob storage. But i wanted to use Stax as i file i writing might end up being very huge. I tried the following.
private void launchXmlStreamWriter() {
AtomicInteger counter = new AtomicInteger(0);
List< Verify > verifications = new ArrayList<>();
Resource readResource = resourceLoader.getResource(String.format(BLOB_RESOURCE_PATTERN, containerName, "9898.xml"));
Resource writeResource = resourceLoader.getResource(String.format(BLOB_RESOURCE_PATTERN, containerName, "9898-out.xml"));
try {
XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
XMLEventReader xmlEventReader = xmlInputFactory.createXMLEventReader(readResource.getInputStream());
JAXBContext readJc = JAXBContext.newInstance(Verify.class);
Unmarshaller unmarshaller = readJc.createUnmarshaller();
OutputStream outputStream = ((WritableResource) writeResource).getOutputStream();
XMLStreamWriter xmlOut = XMLOutputFactory.newFactory().createXMLStreamWriter(outputStream);
xmlOut.writeStartDocument();
xmlOut.writeStartElement("rootElement");
JAXBContext context = JAXBContext.newInstance(Verify.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
while (xmlEventReader.hasNext()) {
if (xmlEventReader.peek().isStartElement() && xmlEventReader.peek().asStartElement().getName().getLocalPart().equals("verify")) {
Verification verification = (Verification) unmarshaller.unmarshal(xmlEventReader);
counter.incrementAndGet();
verifications.add(verification);
if (verifications.size() == 100) {
var accountValidationResponses = process.verify(verifications);
for (Report report : accountValidationResponses) {
JAXBElement<Report> element = new JAXBElement<>(QName.valueOf(""), Report.class, report);
marshaller.marshal(element, xmlOut);
}
verifications = new ArrayList<>();
}
}
xmlEventReader.nextEvent();
}
xmlOut.close();
log.info("Total processed verifications {}", counter.get());
} catch (IOException | XMLStreamException | JAXBException e) {
throw new RuntimeException(e);
}
}
Above code runs through all the elements in xml file but doesnt create any output file.If i change the writeResource to FileSystemResource then a file is created. What am i missing to generate file on azure storage account using Stax?