I have a XML and XSD file corresponds to it. I have just started to learn Spring Framework and I use Spring 3. I should write a code that takes that XML file and assigns it to an object at Java. I searched about it but how can I do it with using Spring (maybe some useful tricks or anything else?)
3 Answers
I recently used Spring OXM & JAXB for that. The class is org.springframework.oxm.jaxb.Jaxb2Marshaller. You can, ofcourse, use any other implementation of org.springframework.oxm.Unmarshaller.
But first You'll need to generate the objects based on Your XSD. For that I used maven-jaxb2-plugin.
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<executions>
<execution>
<id>generate-oxm</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources/META-INF/xsd</schemaDirectory>
<generatePackage>com.stackoverflow.xjc</generatePackage>
</configuration>
</execution>
</executions>
</plugin>
And then configure the marshaller:
@Configuration
public class ApplicationConfiguration {
@Autowired
private ResourcePatternResolver resourceResolver;
@Bean
public Jaxb2Marshaller oxmMarshaller() throws IOException {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("com.stackoverflow.xjc");
marshaller.setSchemas(resourceResolver.getResources("classpath:/META-INF/xsd/*.xsd"));
return marshaller;
}
}
Than just:
File xmlFile = new File("my.xml");
Source source = new StreamSource(new FileInputStream(xmlFile));
JAXBElement<MyXmlRootElemClass> result = oxmMarshaller.unmarshal(source);
MyXmlRootElemClass theObject = result.getValue();
2 Comments
new FileInputStream(xmlFile) line and I can't put try catch to it. Sorry but can you explain more and write more?MyXmlRootElemClass is the class representing the root element of Your XML based on Your XSD - it will be generated by JAXB on generate-sources by maven plugin and will have the same name as Your root element in XML. The last part of my answer is just to give You the idea what goes where in using the (un)marshaller - You may retrieve the XML contents to parse any other way by using any other implementation of Source. But still You'll probably need to handle some exceptions.What is exactly the use case ? Imho the best way is what Roadrunner suggests. But if you are using it in some context, like REST requesting and binding xml response, there are nifty abstractions above, like RestTemplate, where you practically don't have to deal with marshaling at all except for creating bean object
restTemplate.getForObject("http://example.com/hotels/{hotel}/bookings/{booking}", Bean.class);
But as I said, if you are just working with XMLs directly, Jaxb2Marshaller is the way.
Comments
Spring has nothing to do with it. You need some XML databinding tools. There is a lot of them on the market, and my personal favorite is XStream (http://x-stream.github.io/) with XPP backend. Depending on your objects and xml structure other tools may be more suitable