diff --git a/docs/src/site/docbook/reference/readersAndWriters.xml b/docs/src/site/docbook/reference/readersAndWriters.xml index 40e933ab9..77ed703bf 100644 --- a/docs/src/site/docbook/reference/readersAndWriters.xml +++ b/docs/src/site/docbook/reference/readersAndWriters.xml @@ -858,13 +858,6 @@ FOT;2;2;267.34 document, therefore the Spring Batch infrastructure needs to work around this fact (as described below). - On input the reader reads the XML resource until it recognizes a new - fragment is about to start (by matching the tag name by default). The - reader creates a standalone XML document from the fragment (or at least - makes it appear so) and passes the document to a deserializer (typically a - wrapper around Spring WS Unmarshaller) to map the XML to a Java - object. - Figure X: XML Inputs + + The StaxEventItemReader configuration provides a typical setup for the processing of records from an XML input stream. First, lets examine a set of xml records that the StaxEventItemReader can process. + + + +<?xml version="1.0" encoding="UTF-8"?> +<records> + <trade xmlns="http://springframework.org/batch/sample/io/oxm/domain"> + <isin>XYZ0001</isin> + <quantity>5</quantity> + <price>11.39</price> + <customer>Customer1</customer> + </trade> + <trade xmlns="http://springframework.org/batch/sample/io/oxm/domain"> + <isin>XYZ0002</isin> + <quantity>2</quantity> + <price>72.99</price> + <customer>Customer2c</customer> + </trade> + <trade xmlns="http://springframework.org/batch/sample/io/oxm/domain"> + <isin>XYZ0003</isin> + <quantity>9</quantity> + <price>99.99</price> + <customer>Customer3</customer> + </trade> + <trade xmlns="http://springframework.org/batch/sample/io/oxm/domain"> + <isin>XYZ0001</isin> + <quantity>5</quantity> + <price>11.39</price> + <customer>Customer1</customer> + </trade> + <trade xmlns="http://springframework.org/batch/sample/io/oxm/domain"> + <isin>XYZ0002</isin> + <quantity>2</quantity> + <price>72.99</price> + <customer>Customer2c</customer> + </trade> + <trade xmlns="http://springframework.org/batch/sample/io/oxm/domain"> + <isin>XYZ0003</isin> + <quantity>9</quantity> + <price>99.99</price> + <customer>Customer3</customer> + </trade> + <trade xmlns="http://springframework.org/batch/sample/io/oxm/domain"> + <isin>XYZ0001</isin> + <quantity>5</quantity> + <price>11.39</price> + <customer>Customer1</customer> + </trade> + <trade xmlns="http://springframework.org/batch/sample/io/oxm/domain"> + <isin>XYZ0002</isin> + <quantity>2</quantity> + <price>72.99</price> + <customer>Customer2c</customer> + </trade> + <trade xmlns="http://springframework.org/batch/sample/io/oxm/domain"> + <isin>XYZ0003</isin> + <quantity>9</quantity> + <price>99.99</price> + <customer>Customer3</customer> + </trade> +</records> + + + + + To be able to process the XML records we need the following: + + + Root Element Name - this is name of the root element of the fragment that constitutes the object to be mapped in. The example configuration + demonstrates this with the value of trade. + + + Resource - This is a Spring Resource that in the case of this example will abstract the details of opening a file for reading content. + + + Fragment Deserializer - this is the UnMarshalling facility provided by Spring OXM for mapping the XML fragment to an object. + + + + + <property name="itemReader"> + <bean class="org.springframework.batch.io.xml.StaxEventItemReader"> + <property name="fragmentRootElementName" value="trade" /> + <property name="resource" value="data/staxJob/input/20070918.testStream.xmlFileStep.xml" /> + <property name="fragmentDeserializer"> + <bean class="org.springframework.batch.io.xml.oxm.UnmarshallingEventReaderDeserializer"> + <constructor-arg> + <bean class="org.springframework.oxm.xstream.XStreamMarshaller"> + <property name="aliases" ref="aliases" /> + </bean> + </constructor-arg> + </bean> + </property> + </bean> +</property> + + + + Notice that it requires an alias passed in as a map with the + first key and value being the name of the fragment and the object + type that it will be mapped. Then, similar to a FieldSet, the + names of the other elements that map to fields within the object + type are described as key/value pairs in the map. In the + configuration file we can use a spring configuration utility to + described the required alias as follows: + + + <util:map id="aliases"> + <entry key="trade" + value="org.springframework.batch.sample.domain.Trade" /> + <entry key="isin" value="java.lang.String" /> + <entry key="quantity" value="long" /> + <entry key="price" value="java.math.BigDecimal" /> + <entry key="customer" value="java.lang.String" /> + </util:map> + + + + On input the reader reads the XML resource until it recognizes a new + fragment is about to start (by matching the tag name by default). The + reader creates a standalone XML document from the fragment (or at least + makes it appear so) and passes the document to a deserializer (typically a + wrapper around Spring WS Unmarshaller) to map the XML to a Java + object. + + + In summary, if you were to see this in scripted code like Java the injection provided by the spring configuration would look something like the following: + + + + def xmlStaxEventItemReader = new StaxEventItemReader() + resource = new ByteArrayResource(xmlResource.getBytes()) + + def aliases = ["trade":"org.springframework.batch.sample.domain.Trade", + "isin":"java.lang.String", + "quantity":"long", + "price":"java.math.BigDecimal", + "customer":"java.lang.String"] + def marshaller = new XStreamMarshaller() + marshaller.setAliases(aliases) + xmlStaxEventItemReader.setFragmentDeserializer(new UnmarshallingEventReaderDeserializer(marshaller)) + xmlStaxEventItemReader.setResource(resource) + xmlStaxEventItemReader.setFragmentRootElementName("trade") + def executionContext = new ExecutionContext() + xmlStaxEventItemReader.open(executionContext); + + def hasNext = true + while (hasNext) { + trade = xmlStaxEventItemReader.read() + if (trade == null) { + hasNext = false + } else { + println trade + } + } + + + Output works symetrically to input. Java object is passed to a serializer (typically a wrapper around Spring WS Marshaller) which writes to output using a custom event writer that filters the StartDocument and @@ -927,4 +1079,4 @@ FOT;2;2;267.34 - \ No newline at end of file +