Tickaroo / tikxml

Modern XML Parser for Android
Apache License 2.0
423 stars 44 forks source link

Dynamic root tag name #140

Open heyarny opened 4 years ago

heyarny commented 4 years ago

I was looking for a simple solution on how to proceed when there are different responses.

<response1>
  <foo>foo</foo>
</response1>
<response2>
  <bar>bar</bar>
</response2>

I could find some info about dynamic element within root, but not the root itself. Is this not supported by this library?

sockeqwe commented 4 years ago

I'm not 100% sure what you mean with "dynamic" but yes, that is possible you have to annotate 2 classes though:

@Xml
class Response1 {
  @PropertyElement
  String foo;
}
@Xml
class Response2 {
  @PropertyElement
  String bar;
}

When parsing you just have to tell TikXML to either parse Response1.class or Response2.class (that's what our Retrofit converter does under the hood)

heyarny commented 4 years ago

What if you don't know what response you're expecting? Lets say there is an error while you expect Response1:

<error>
  <code>...</code>
</error>

Or there are different response types inherited from some "BaseResponse". Everything quite possible scenarios.

Just like this case: https://github.com/Tickaroo/tikxml/blob/master/docs/AnnotatingModelClasses.md#polymorphism-and-inheritance

But on root element.

heyarny commented 4 years ago

Take a look at this unresolved question years ago: https://stackoverflow.com/questions/34046908/retrofit-and-simplexml-for-unknown-root-element

sockeqwe commented 4 years ago

No, it's not supported and I think error responses in general as return value is not best practice for REST API's (use HTTP Status codes)

With that said, reading such xml might work as following (haven't tried it yet, so you have to give it a try on your own):

@Xml 
class Response {

   @Element
    Foo foo;

   @Element
   Error error;
}

So you always parse into Response.class but either Foo or Error is null.

Writing xml is defenitely not supported as it will produce

<response>
   <foo>...</foo>
</response>

or

<response>
   <error>...</error>
</response>
heyarny commented 4 years ago

I know at least one xml protocol (by CISCO) which is actually based on different root tags and those are not bound to specific endpoints. So you'll never know what response may come. So it is not something uncommon.

Will convert the responses manually then. Thanks

PS: you could change this to "feature request", if anyone cares..

sockeqwe commented 4 years ago

You could do some "semi automated parsing" if you know all possible root tags by writing your own TypeAdapter that reads the root tag and then delegates to other (generated by annotation processors) TypeAdapter that then will do further xml parsing of child notes ... Same for writing xml in case you need it.