Reputation: 37
I am new to beanio. Can some one please help me with this. I am trying to process the input file, which looks like below, where existence of Item elements inside Data element is numerous:
<?xml version="1.0" encoding="windows-1252"?>
<ROOT xmlns="http://www.post.ch/schemas/dfu/2006/20/Report11">
<Sender>
<Provider>
<Data>
<Item SendingID="314" ItemID="996099999902916713" IdentCode="996099999902916713" AdrZ1="Meier" AdrZ2="" AdrZ3="" AdrZ4="Dorfweg" AdrZ5="6" AdrZ6="4117" AdrZ7="Burg im Leimental" DFUTransferDateTime="2019-07-18T13:24:56" ItemWeight="480" EventDateTime="2019-07-22T04:13:59" EventNumber="9209" EventDescription="Ordre voisin souhaité" EventNumber_Sub="" Event_SubDescription="" EventZipCode="303001" PrZl="SAZU" DeliveredTo="" TrackAndTrace="https://service.post.ch/EasyTrack/secure/GKDirectSearch.do?formattedParcelCodes=996099999902916713;&lang=fr" Status="31" StatusDescription="Prêt pour la distribution" ExpectedDeliveryDate="27.07.19" DeadlinePickup="" />
<Item SendingID="313" ItemID="996099999902916585" IdentCode="996099999902916585" AdrZ1="Müllerer" AdrZ2="" AdrZ3="" AdrZ4="Gärischstrasse" AdrZ5="27" AdrZ6="4512" AdrZ7="Bellach" DFUTransferDateTime="2019-07-17T13:51:23" ItemWeight="1080" EventDateTime="2019-07-22T07:32:59" EventNumber="4000" EventDescription="Distribué" EventNumber_Sub="" Event_SubDescription="" EventZipCode="462070" PrZl="" DeliveredTo=" " TrackAndTrace="https://service.post.ch/EasyTrack/secure/GKDirectSearch.do?formattedParcelCodes=996099999902916585;&lang=fr" Status="61" StatusDescription="Distribué" ExpectedDeliveryDate="22.07.19" DeadlinePickup="" />
</Data>
</Provider>
</Sender>
</ROOT>
My stream in beanio xml looks like below:
<stream name="swisspost" format="xml" xmlName="ROOT" xmlNamespace="http://www.post.ch/schemas/dfu/2006/20/Report11">
<record name="shippingData" xmlName="Sender" class="com.test.eventproc.carrier.data.ShippingDataDO">
<property name="carrierMoniker" value="swisspost"/>
<segment name="Provider">
<segment name="Data">
<segment name="Item">
<field name="trackingNumber" xmlName="IdentCode" xmlType="attribute"></field>
</segment>
<segment name="shippingDetail" xmlName="Item" xmlType="element" class="com.test.eventproc.carrier.data.ShippingDetailDO">
<field name="trackingNumber" xmlName="IdentCode" xmlType="attribute"></field>
<field name="eventCode" xmlName="EventNumber" xmlType="attribute"></field>
<field name="eventDate" xmlName="EventDateTime" xmlType="attribute"></field>
<field name="eventName" xmlName="EventDescription" xmlType="attribute"></field>
</segment>
</segment>
</segment>
</record>
</stream>
As per my above stream only first Item element value is processed and the program exits. Is there a way, i can process all Item elements? Below is the code, i am using to populate BeanReader object:
StreamFactory factory = StreamFactory.newInstance();
factory.loadResource("mapping.xml");//mapping.xml is my bean-io mapping file.
File originalFile = convert(file);//file is the input xml flat file
FileInputStream inputStream = new FileInputStream(originalFile);
BeanReader reader = factory.createReader(streamName, new InputStreamReader(inputStream));
Object record;
List<ShippingDataDO> shippingDataDOs = new ArrayList<ShippingDataDO>();
while ((record = reader.read()) != null) {
ShippingDataDO shippingDataDO = (ShippingDataDO) record;
shippingDataDOs.add(shippingDataDO);
}
I tried mapping xml something like below. But, now no records are retrieved from the input flat xml file.
<stream name="swisspost" format="xml" xmlName="ROOT" xmlNamespace="http://www.post.ch/schemas/dfu/2006/20/Report11">
<record name="Sender">
<segment name="Provider">
<segment name="Data">
<segment name="shippingData" xmlName="Item" maxOccurs="unbounded" collection="list" class="com.narvar.carrier.utilities.pojo.ShippingDataDO">
<property name="carrierMoniker" value="swisspost"/>
<field name="trackingNumber" xmlName="IdentCode" xmlType="attribute"></field>
</segment>
<segment name="shippingDetail" xmlName="Item" xmlType="element" maxOccurs="unbounded" class="com.narvar.carrier.utilities.pojo.ShippingDetailDO" collection="list">
<field name="trackingNumber" xmlName="IdentCode" xmlType="attribute"></field>
<field name="eventCode" xmlName="EventNumber" xmlType="attribute"></field>
<field name="eventDate" xmlName="EventDateTime" xmlType="attribute"></field>
<field name="eventName" xmlName="EventDescription" xmlType="attribute"></field>
</segment>
</segment>
</segment>
</record>
</stream>
Upvotes: 0
Views: 2109
Reputation: 2636
You just need to make a small adjustment to your mapping file. You must tell BeanIO that the shippingDetail
segment is a repeatable segment, by setting the maxOccurs
attribute to unbounded
and setting the collection
attribute to list
.
See the Repeating Segments documentation for more detail, in essence:
Similar to repeating fields, BeanIO supports repeating segments, which may be bound to a collection of bean objects.
In our mapping file, in order to bind a segment to a collection, simply set it's collection attribute to the fully qualified class name of a java.util.Collection or java.util.Map subclass, or to one of the collection type aliases
Repeating segments can declare the number of occurrences using the minOccurs and maxOccurs attributes. If not declared, minOccurs will default to 1, and maxOccurs will default to the minOccurs value or 1, whichever is greater.
Your shippingDetail
segment then becomes:
<segment name="shippingDetail" xmlName="Item" xmlType="element" maxOccurs="unbounded"
class="com.test.eventproc.carrier.data.ShippingDetailDO" collection="list">
<field name="trackingNumber" xmlName="IdentCode" xmlType="attribute"></field>
<field name="eventCode" xmlName="EventNumber" xmlType="attribute"></field>
<field name="eventDate" xmlName="EventDateTime" xmlType="attribute"></field>
<field name="eventName" xmlName="EventDescription" xmlType="attribute"></field>
</segment>
Hope this help!
Upvotes: 1