Discussion:
[jibx-users] Cannot use flexible=true with collection
Bob Smith
2010-10-19 12:53:56 UTC
Permalink
Hello,

I have been using JiBX for a couple months on basic XML files and I am really pleased especially by the performance.

I am now trying to bind an RSS format.
My issue is that, in RSS, the list of items is not embedded in an <items> tag.
Example:
<rss>
<channel>
<item />
<item />
<item />
</channel>
</rss>

My binding is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<binding name="binding" package="my.jibx.rss">
<mapping name="rss" class="my.jibx.rss.Feed">
<structure name="channel" field="channel" map-as="channel" />
</mapping>
<mapping abstract="true" type-name="channel" class="my.jibx.rss.Channel" ordered="false" flexible="true">
<value style="element" name="link" field="link" usage="optional" />
<value style="element" name="title" field="title" usage="optional" />
<value style="element" name="description" field="description" usage="optional" />
<collection field="items" create-type="java.util.ArrayList" ordered="false" />
</mapping>
<mapping name="item" class="my.jibx.rss.Item" ordered="false" flexible="true">
<value style="element" name="title" field="title" usage="optional" />
<value style="element" name="description" field="description" usage="optional" />
<structure name="image" field="image" type="my.jibx.rss.Image" usage="optional" ordered="false">
<value style="element" name="url" field="url" />
</structure>
<structure name="enclosure" field="enclosure" type="my.jibx.rss.Enclosure" usage="optional" ordered="false">
<value style="attribute" name="url" field="url" />
<value style="attribute" name="type" field="type" usage="optional" />
<value style="attribute" name="length" field="length" usage="optional" />
</structure>
</mapping>
</binding>


Since I do not want to handle some elements that are unnecessary to me and that others apps may add with their own namespace, I try to use flexible="true" on the Channel mapping.
However, I cannot use flexible="true" on the Channel mapping because the collection of items has no name. Error:

Error: All child components must define element names for flexible='true'; on collection element at (line 10, col 83, in rss-binding.xml)


And I cannot use a name since there is no eclosing tag in RSS.
How can this type of collection be handled using JiBX?

Thank you for your help.
Bob
Archie Cobbs
2010-10-19 16:27:31 UTC
Permalink
Ironically, things get very inflexible when you specify flexible="true".
Here are some other issues I've found:

JIBX-402 <http://jira.codehaus.org/browse/JIBX-402>: JiBX fails when
abstract type is used with flexible="true"
JIBX-397 <http://jira.codehaus.org/browse/JIBX-397>: Allow setting
flexible="true" and ordered="false" at the same time

I don't really understand why though. It seems like there should be a flag
in the code somewhere that says whether to reject or ignore unknown tags,
and why simply changing that flag causes all these other problems.

-Archie
Post by Bob Smith
Hello,
I have been using JiBX for a couple months on basic XML files and I am
really pleased especially by the performance.
I am now trying to bind an RSS format.
My issue is that, in RSS, the list of items is not embedded in an <items> tag.
<rss>
<channel>
<item />
<item />
<item />
</channel>
</rss>
<?xml version="1.0" encoding="UTF-8"?>
<binding name="binding" package="my.jibx.rss">
<mapping name="rss" class="my.jibx.rss.Feed">
<structure name="channel" field="channel" map-as="channel" />
</mapping>
<mapping abstract="true" type-name="channel" class="my.jibx.rss.Channel"
ordered="false" flexible="true">
<value style="element" name="link" field="link" usage="optional" />
<value style="element" name="title" field="title" usage="optional" />
<value style="element" name="description" field="description" usage="optional" />
<collection field="items" create-type="java.util.ArrayList"
ordered="false" />
</mapping>
<mapping name="item" class="my.jibx.rss.Item" ordered="false"
flexible="true">
<value style="element" name="title" field="title" usage="optional" />
<value style="element" name="description" field="description" usage="optional" />
<structure name="image" field="image" type="my.jibx.rss.Image"
usage="optional" ordered="false">
<value style="element" name="url" field="url" />
</structure>
<structure name="enclosure" field="enclosure"
type="my.jibx.rss.Enclosure" usage="optional" ordered="false">
<value style="attribute" name="url" field="url" />
<value style="attribute" name="type" field="type" usage="optional" />
<value style="attribute" name="length" field="length" usage="optional" />
</structure>
</mapping>
</binding>
Since I do not want to handle some elements that are unnecessary to me and
that others apps may add with their own namespace, I try to use
flexible="true" on the Channel mapping.
However, I cannot use flexible="true" on the Channel mapping because the
Error: All child components must define element names for flexible='true';
on collection element at (line 10, col 83, in rss-binding.xml)
And I cannot use a name since there is no eclosing tag in RSS.
How can this type of collection be handled using JiBX?
Thank you for your help.
Bob
------------------------------------------------------------------------------
Download new Adobe(R) Flash(R) Builder(TM) 4
The new Adobe(R) Flex(R) 4 and Flash(R) Builder(TM) 4 (formerly
Flex(R) Builder(TM)) enable the development of rich applications that run
across multiple browsers and platforms. Download your free trials today!
http://p.sf.net/sfu/adobe-dev2dev
_______________________________________________
jibx-users mailing list
https://lists.sourceforge.net/lists/listinfo/jibx-users
--
Archie L. Cobbs
Bob Smith
2010-10-21 14:30:45 UTC
Permalink
Hello,

Thank you Archie for the insight on "flexible".

I was able to work around my issue, thanks to a few previous messages
on the list.
However, this works because I am only reading RSS format, never
writing it (which may need another binding).

Here is what works for me:

<binding name="binding" package="my.jibx.rss" direction="input">
  <mapping name="rss" class="my.jibx.rss.Feed">
    <structure name="channel" field="channel"
type="my.jibx.rss.Channel" ordered="false" flexible="true"
allow-repeats="true">
      <value style="element" name="link" field="link" usage="optional" />
      <value style="element" name="title" field="title" usage="optional" />
      <value style="element" name="description" field="description"
usage="optional" />
      <structure name="item" type="my.jibx.rss.Item"
set-method="addItem" ordered="false" flexible="true">
        <value style="element" name="title" field="title" usage="optional" />
        <value style="element" name="description" field="description"
usage="optional" />
        <structure name="image" field="image" type="my.jibx.rss.Image"
usage="optional" ordered="false" flexible="true">
          <value style="element" name="url" field="url" />
        </structure>
        <structure name="enclosure" field="enclosure"
type="my.jibx.rss.Enclosure" usage="optional" ordered="false"
flexible="true">
          <value style="attribute" name="url" field="url" />
          <value style="attribute" name="type" field="type" usage="optional" />
          <value style="attribute" name="length" field="length"
usage="optional" />
        </structure>
      </structure>
    </structure>
  </mapping>
</binding>

The addItem(Item) method of the Channel class adds the given item to
the List<Item> each time an Item is unmarshalled.

Best,
Bob



2010/10/19 Archie Cobbs <>
JIBX-402: JiBX fails when abstract type is used with flexible="true"
JIBX-397: Allow setting flexible="true" and ordered="false" at the same time
I don't really understand why though. It seems like there should be a flag in the code somewhere that says whether to reject or ignore unknown tags, and why simply changing that flag causes all these other problems.
-Archie
Post by Bob Smith
Hello,
I have been using JiBX for a couple months on basic XML files and I am really pleased especially by the performance.
I am now trying to bind an RSS format.
My issue is that, in RSS, the list of items is not embedded in an <items> tag.
<rss>
 <channel>
   <item />
   <item />
   <item />
 </channel>
</rss>
<?xml version="1.0" encoding="UTF-8"?>
<binding name="binding" package="my.jibx.rss">
 <mapping name="rss" class="my.jibx.rss.Feed">
   <structure name="channel" field="channel" map-as="channel" />
 </mapping>
 <mapping abstract="true" type-name="channel" class="my.jibx.rss.Channel" ordered="false" flexible="true">
   <value style="element" name="link" field="link" usage="optional" />
   <value style="element" name="title" field="title" usage="optional" />
   <value style="element" name="description" field="description" usage="optional" />
   <collection field="items" create-type="java.util.ArrayList" ordered="false" />
 </mapping>
 <mapping name="item" class="my.jibx.rss.Item" ordered="false" flexible="true">
   <value style="element" name="title" field="title" usage="optional" />
   <value style="element" name="description" field="description" usage="optional" />
   <structure name="image" field="image" type="my.jibx.rss.Image" usage="optional" ordered="false">
     <value style="element" name="url" field="url" />
   </structure>
   <structure name="enclosure" field="enclosure" type="my.jibx.rss.Enclosure" usage="optional" ordered="false">
     <value style="attribute" name="url" field="url" />
     <value style="attribute" name="type" field="type" usage="optional" />
     <value style="attribute" name="length" field="length" usage="optional" />
   </structure>
 </mapping>
</binding>
Since I do not want to handle some elements that are unnecessary to me and that others apps may add with their own namespace, I try to use flexible="true" on the Channel mapping.
Error: All child components must define element names for flexible='true'; on collection element at (line 10, col 83, in rss-binding.xml)
And I cannot use a name since there is no eclosing tag in RSS.
How can this type of collection be handled using JiBX?
Thank you for your help.
Bob
------------------------------------------------------------------------------
Download new Adobe(R) Flash(R) Builder(TM) 4
The new Adobe(R) Flex(R) 4 and Flash(R) Builder(TM) 4 (formerly
Flex(R) Builder(TM)) enable the development of rich applications that run
across multiple browsers and platforms. Download your free trials today!
http://p.sf.net/sfu/adobe-dev2dev
_______________________________________________
jibx-users mailing list
https://lists.sourceforge.net/lists/listinfo/jibx-users
--
Archie L. Cobbs
------------------------------------------------------------------------------
Download new Adobe(R) Flash(R) Builder(TM) 4
The new Adobe(R) Flex(R) 4 and Flash(R) Builder(TM) 4 (formerly
Flex(R) Builder(TM)) enable the development of rich applications that run
across multiple browsers and platforms. Download your free trials today!
http://p.sf.net/sfu/adobe-dev2dev
_______________________________________________
jibx-users mailing list
https://lists.sourceforge.net/lists/listinfo/jibx-users
Dennis Sosnoski
2010-11-19 02:37:52 UTC
Permalink
The issue with "flexible" unmarshalling is that JiBX normally generates
code based on the expected order of elements in order to get the most
efficient processing - at any point in the unmarshalling it can just
check for the next expected element, and if it's not found skip to the
following one, an approach that works very well with a pull parser.
So-called "flexible" unmarshalling instead requires that it look at the
element name and then fan-out for processing based on that name.

For 2.0 I'm planning better handling of this case, but it's always going
to be somewhat ugly.

Incidentally, http://jira.codehaus.org/browse/JIBX-397 appears to be
mis-titled - it looks like it should be "Allow setting flexible='true'
and ordered='true' at the same time. I'm looking into an easy
work-around for this case now, based on using a DOM mapper that handles
anything other than the specified namespace.

- Dennis

Dennis M. Sosnoski
Java SOA and Web Services Consulting <http://www.sosnoski.com/consult.html>
Axis2/CXF/Metro SOA and Web Services Training
<http://www.sosnoski.com/training.html>
Web Services Jump-Start <http://www.sosnoski.com/jumpstart.html>
Post by Archie Cobbs
Ironically, things get very inflexible when you specify
JIBX-402 <http://jira.codehaus.org/browse/JIBX-402>: JiBX fails when
abstract type is used with flexible="true"
JIBX-397 <http://jira.codehaus.org/browse/JIBX-397>: Allow setting
flexible="true" and ordered="false" at the same time
I don't really understand why though. It seems like there should be a
flag in the code somewhere that says whether to reject or ignore
unknown tags, and why simply changing that flag causes all these other
problems.
-Archie
Hello,
I have been using JiBX for a couple months on basic XML files and
I am really pleased especially by the performance.
I am now trying to bind an RSS format.
My issue is that, in RSS, the list of items is not embedded in an <items> tag.
<rss>
<channel>
<item />
<item />
<item />
</channel>
</rss>
<?xml version="1.0" encoding="UTF-8"?>
<binding name="binding" package="my.jibx.rss">
<mapping name="rss" class="my.jibx.rss.Feed">
<structure name="channel" field="channel" map-as="channel" />
</mapping>
<mapping abstract="true" type-name="channel"
class="my.jibx.rss.Channel" ordered="false" flexible="true">
<value style="element" name="link" field="link" usage="optional" />
<value style="element" name="title" field="title"
usage="optional" />
<value style="element" name="description" field="description"
usage="optional" />
<collection field="items" create-type="java.util.ArrayList" ordered="false" />
</mapping>
<mapping name="item" class="my.jibx.rss.Item" ordered="false" flexible="true">
<value style="element" name="title" field="title"
usage="optional" />
<value style="element" name="description" field="description"
usage="optional" />
<structure name="image" field="image" type="my.jibx.rss.Image"
usage="optional" ordered="false">
<value style="element" name="url" field="url" />
</structure>
<structure name="enclosure" field="enclosure"
type="my.jibx.rss.Enclosure" usage="optional" ordered="false">
<value style="attribute" name="url" field="url" />
<value style="attribute" name="type" field="type"
usage="optional" />
<value style="attribute" name="length" field="length"
usage="optional" />
</structure>
</mapping>
</binding>
Since I do not want to handle some elements that are unnecessary
to me and that others apps may add with their own namespace, I try
to use flexible="true" on the Channel mapping.
However, I cannot use flexible="true" on the Channel mapping
Error: All child components must define element names for
flexible='true'; on collection element at (line 10, col 83, in
rss-binding.xml)
And I cannot use a name since there is no eclosing tag in RSS.
How can this type of collection be handled using JiBX?
Thank you for your help.
Bob
------------------------------------------------------------------------------
Download new Adobe(R) Flash(R) Builder(TM) 4
The new Adobe(R) Flex(R) 4 and Flash(R) Builder(TM) 4 (formerly
Flex(R) Builder(TM)) enable the development of rich applications that run
across multiple browsers and platforms. Download your free trials today!
http://p.sf.net/sfu/adobe-dev2dev
_______________________________________________
jibx-users mailing list
https://lists.sourceforge.net/lists/listinfo/jibx-users
--
Archie L. Cobbs
------------------------------------------------------------------------------
Download new Adobe(R) Flash(R) Builder(TM) 4
The new Adobe(R) Flex(R) 4 and Flash(R) Builder(TM) 4 (formerly
Flex(R) Builder(TM)) enable the development of rich applications that run
across multiple browsers and platforms. Download your free trials today!
http://p.sf.net/sfu/adobe-dev2dev
_______________________________________________
jibx-users mailing list
https://lists.sourceforge.net/lists/listinfo/jibx-users
Archie Cobbs
2010-11-19 15:15:01 UTC
Permalink
Post by Dennis Sosnoski
Incidentally, http://jira.codehaus.org/browse/JIBX-397 appears to be
mis-titled - it looks like it should be "Allow setting flexible='true' and
ordered='true' at the same time. I'm looking into an easy work-around for
this case now, based on using a DOM mapper that handles anything other than
the specified namespace.
You're right, it should have said "Allow setting flexible='true' and
ordered='true' at the same time". Sorry about that.
Post by Dennis Sosnoski
The issue with "flexible" unmarshalling is that JiBX normally generates
code based on the expected order of elements in order to get the most
efficient processing - at any point in the unmarshalling it can just check
for the next expected element, and if it's not found skip to the following
one, an approach that works very well with a pull parser. So-called
"flexible" unmarshalling instead requires that it look at the element name
and then fan-out for processing based on that name.
For 2.0 I'm planning better handling of this case, but it's always going to
be somewhat ugly.
I'll take your word for it... but I'm still curious about this (pardon my
ignorance). If this is too complicated to explain just say so and I'll stop
asking :-)

The difficulty seems backwards. It seems that supporting flexible="true"
should actually be easier in the ordered="true" case than in the
ordered="false" case. In the ordered="true" case, if you see something other
than the next expected element, you just skip it and go on to the next one
(as you described above). It seems like only in the ordered="false" case do
you need to do any kind of lookup operation...

Ah, perhaps you're requiring the parser to distinguish between an unknown
element and an out-of-order element? Then a lookup would be required. But a
lookup is required in the ordered="false" case, so we already know how to do
that... ?

-Archie
--
Archie L. Cobbs
Dennis Sosnoski
2010-11-19 19:04:22 UTC
Permalink
Post by Dennis Sosnoski
The issue with "flexible" unmarshalling is that JiBX normally
generates code based on the expected order of elements in order to
get the most efficient processing - at any point in the
unmarshalling it can just check for the next expected element, and
if it's not found skip to the following one, an approach that
works very well with a pull parser. So-called "flexible"
unmarshalling instead requires that it look at the element name
and then fan-out for processing based on that name.
For 2.0 I'm planning better handling of this case, but it's always
going to be somewhat ugly.
I'll take your word for it... but I'm still curious about this (pardon
my ignorance). If this is too complicated to explain just say so and
I'll stop asking :-)
The difficulty seems backwards. It seems that supporting
flexible="true" should actually be easier in the ordered="true" case
than in the ordered="false" case. In the ordered="true" case, if you
see something other than the next expected element, you just skip it
and go on to the next one (as you described above). It seems like only
in the ordered="false" case do you need to do any kind of lookup
operation...
Ah, perhaps you're requiring the parser to distinguish between an
unknown element and an out-of-order element? Then a lookup would be
required. But a lookup is required in the ordered="false" case, so we
already know how to do that... ?
With ordered='false' you can just have a bag of elements and accept any
one of them at any time, basically doing a switch statement on the
element name to handle it. This is what JAXB and .Net do by default -
which means they deliberately ignore the ordering of elements in the
schema, helping to create interoperability problems with tools that *do*
look at schema ordering.

What makes flexible='true' combined with ordered='true' more complex is
the need to support optional elements. At any point in the parse, the
next element in the input may be the next element in your schema
sequence, or *any following element up to and including the first
required element*, or any other element (which should be ignored).
Probably the best way to handle this in code is to use a state index for
the elements in the sequence (state 'n' meaning we've parsed the first
'n' elements in the sequence), and again use a switch statement on the
element name but this time combine it with some state logic (to assure
that the known elements are in order, and that required ones aren't
skipped). But then what do you do with the same element name used more
than once at different points in the sequence?

So like I said, it's ugly. :-)

- Dennis
Archie Cobbs
2010-11-19 19:49:37 UTC
Permalink
What makes flexible='true' combined with ordered='true' more complex is the
need to support optional elements. At any point in the parse, the next
element in the input may be the next element in your schema sequence, or
*any following element up to and including the first required element*, or
any other element (which should be ignored). Probably the best way to handle
this in code is to use a state index for the elements in the sequence (state
'n' meaning we've parsed the first 'n' elements in the sequence), and again
use a switch statement on the element name but this time combine it with
some state logic (to assure that the known elements are in order, and that
required ones aren't skipped). But then what do you do with the same element
name used more than once at different points in the sequence?
Thanks, now it makes sense... I wasn't thinking of the impact of optional
elements.

This comment is totally blue sky but this complexity makes me wonder if it
would make more sense to implement JiBX with the assistance of a
context-free grammar parsing tool like Antlr (the Java equivalent of
bison/yacc). The terminals in your language would be XML parse events and
the input document would be the streamed XML parse. Then the JiBX compiler's
job would be to generate the grammar file (including semantic actions)
appropriate for the parse.

Anyway thanks for the explanation.

-Archie
--
Archie L. Cobbs
Loading...