Thomas Jones-Low wrote:

...
XML File:
<person>
<primary> <street>124 main street</street><city>new york</city>
<state>NY</state> <zip>000000</zip>
</primary>
<secondary> <street>142 tree street, apt 14</street>
<city>Burlington</city><state>MI</state>
<zip>00000</zip>
</secondary>
</person>

Binding attempt 1:
<binding>
<namespace uri="http://www.softstart.com/"; default="elements" />
<mapping name="person" class="Person" field="person">
<structure field="primary" map-as="Address"/>
<structure name="secondary" usage="optional">
<collection field="secondary" item-type="Address"/>
</structure>
</mapping>
<mapping name="primary" class="Address">
<value name="street" field="street"/>
<value name="city" field="city" />
<value name="state" field="state" />
<value name="zip" field="zip" />
</mapping>
</binding>

This is saying that you have an optional <secondary> element as a peer of the <primary> element under <person>, and that the <secondary> element contains a collection of <primary> elements - not a match to your data.



...
Getting frustrated, I tried to flatten the listing, which worked. And I discovered that the structure element will take a class attribute, even through neither the documentation nor the XSD say it's allowed. That is, the following is accepted and works as expected:


<binding>
<namespace uri="http://www.softstart.com/"; default="elements" />
<mapping name="person" class="Person" field="person">
<structure field="primary" name="primary" class="Address">
<value name="street" field="street"/>
<value name="city" field="city" />
<value name="state" field="state" />
<value name="zip" field="zip" />
</structure>
<structure usage="optional">
<collection field="secondary" item-type="Address"/>
</structure>
</mapping>
<mapping name="secondary" class="Address">
<value name="street" field="street"/>
<value name="city" field="city" />
<value name="state" field="state" />
<value name="zip" field="zip" />
</mapping>
</binding>

The class attribute is only used with a <mapping> element. The current code doesn't check for unknown attributes, so it won't complain if you add in something that's not relevant. That's the case for your class attribute on the <structure> element. If you remove this attribute everything should work the same.


For beta 4 I'll be checking for unknown attributes, just to avoid the confusion factor this causes for users.


The other way I got this to apparently work was using the label/using construct. Which has a big warning that it is being depreciated. Binding is as follows:


<binding>
<namespace uri="http://www.softstart.com/"; default="elements" />
<mapping name="person" class="Person" field="person">
<structure field="primary" name="primary" using="ADDRESS"/>
<structure name="secondary" usage="optional">
<collection field="secondary" item-type="Address"/>
</structure>
</mapping>
<mapping name="secondary" class="Address" label="ADDRESS">
<value name="street" field="street"/>
<value name="city" field="city" />
<value name="state" field="state" />
<value name="zip" field="zip" />
</mapping>
</binding>

Of course this doesn't work the other way around, with the address map for primary, and the using on the secondary structure/collection.

<binding>
<namespace uri="http://www.softstart.com/"; default="elements" />
<mapping name="person" class="Person" field="person">
<structure field="primary" map-as="Address"/>
<structure name="secondary" usage="optional" using="ADDRESS">
<collection field="secondary" item-type="Address"/>
</structure>
</mapping>
<mapping name="primary" class="Address" label="ADDRESS">
<value name="street" field="street"/>
<value name="city" field="city" />
<value name="state" field="state" />
<value name="zip" field="zip" />
</mapping>
</binding>

As I understand it you have a collection of <secondary>s, not a <secondary> that contains a collection of <primary> (which is what the above binding definition says). This approach should work if you structure the binding properly, which would be:


<structure field="primary" map-as="Address"/>
<collection field="secondary" usage="optional">
<structure name="secondary" using="ADDRESS"/>
</collection>

No guarantees on this, though, since the whole label/using approach has some broken pieces - that's why it's going to be replaced with a more stable alternative.

As for the "correct" way, JiBX actually gives you multiple alternatives in most cases. The binding further up is fine; I think you should also be able to define the Address class with a <mapping abstract="true"...> which doesn't specify a name, then fill in the name on the references to it:

<structure field="primary" name="primary" map-as="Address"/>
<collection field="secondary" usage="optional">
<structure name="secondary" map-as="Address"/>
</collection>

The label/using approach also works, though this will need to change in the future.

The whole focus of the remaining refactoring for beta 4 and production release is to make the different types of binding components work as consistently as possible. I'm also trying to add more direct feedback to the user, so when they use something incorrectly they find out about it immediately. I'll also try to clarify when to use a <mapping>/<structure>/<template> in the documentation (where <template> is the replacement for label/using).

- Dennis

- Dennis


-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 - digital self defense, top technical experts, no vendor pitches, unmatched networking opportunities. Visit www.blackhat.com
_______________________________________________
jibx-users mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jibx-users

Reply via email to