Parse xml with same properties but different parent elements using JAXB - java

I'm using JAXB to parse some xml provided by a separate service. They provide this xml as different elements but I treat them the same. I.E.
<ElementA>
<name>foo</name>
<type>bar</type>
</ElementA>
<ElementB>
<name>foo1</name>
<type>bar1</type>
</ElementB>
This is how in the data but when I parse/unmarshall it with JAXB I want it to know that ElementA and ElementB are both just instances of the Element class and unmarshall it as such. Currently I am doing this by using the XmlRegistry to say that ElementA is an Element and ElementB is an Element.
However at some point we might receive ElementC and ElementD so I would like a way for JAXB to know those are also just Element without having to add an entry to the XmlRegistry everytime.

Related

XML UnMarshalling based on child nodes

I recently got an old XML over HTTP API. It has few response types and all those responses have no namespace or type attributes. They all have the same root node and then different set of child nodes.
Is there a way in java to UnMarshall such XMLs ? It would be like using child nodes as discriminator fields. Two sample responses are given below.
<Response>
<A1/>
<A2/>
</Response>
<Response>
<B1/>
<B2/>
</Response>
The best approach really depends on what you want to do. If you just want to unmarshal the data you could define a model using JAXB, for instance, which includes all the potential child elements. Then when you unmarshalled an instance documents only the child elements actually present in the document would have values.
If you instead want to have separate models for the different response variations your best approach would be to use a BufferedInputStream and call mark() at the start, then read enough of the document with a pull parser such as XMLStreamReader to determine the actual response type. Then you can reset() the stream to the start of the document and start over using JAXB with the appropriate data model.

How to tell XStream to ignore child elements that have the 'class' attribute

I have some persisted XML that was generated by XStream, and looks like:
<CalculationDefinition>
<id>47</id>
<version>3</version>
<name>RHO error (pts)</name>
<expression class="com.us.provider.expression.AbsoluteValue">
....
</expression>
</CalculationDefinition>
I want to persist this content differently now, and want to tell XStream to simply ignore the expression element entirely. There's many links around that talk about how to do this with a MapperWrapper (eg XStream JIRA) but as far I can tell it doesn't work for an element that has a 'class' attribute.
This can be worked around by leaving an 'expression' field in the CalculationDefinition, but I'd rather not have to keep it there now that it's not used in code.
You could filter the incoming XML using XSL and removing the expression nodes, before passing it to XStream.

jaxb umarshalling problem: can not get the attributes on empty xml tags

I have to unmarshal a xml-soap string to a Java object using JAXB. The XML contains a lot of empty tags with filled attributes, for instance most information in the message is relayed as follows:
<ID code="123" codeSystem="12.12.12"/>
I am interested in the attributes.
Problem:
If I inspect the object after the unmarshalling, all the empty tags (like the one above) have no representation (e.g. are null) in the Java object. Only the filled tags (e.g. 123 have been added to the Java object.
Maybe this behaviour is conform xml standards, but I am still interested in the attributes.
Can someone tell me if there is a way to get the attributes??
Possible workaround: to give each element a default value ("") when its null by binding it to an adapter using the bindings-file. But I only succeeded in doing this for simple-types.
Used versions: we are using the jaxb implementation in Java 1.6
Many thanks.
Wybrand.
As there is no default value for XML attributes I would implement the initialization code in the afterUnmarshal method. There you could check all attributes you are interested in and set them to a valid non-null value.
For details how to use afterUnmarshal see: How can I have JAXB call a method after it has completed unmarshalling an XML file into an object?
I solved the problem. But the problem was not JAXB.
The party which sends the xml which I have to umarshall puts a 'null namespace' in the element declaration.
Xml fragment:
The id element has in its declaration xmlns="". (I presume this is a bug) and the root tag has the declaration xmlns:ns3="urn:hl7-org:v3"
For this reason (I think) the jaxb unmarshaller does not see the id element as part of the message.

XML without root element in JAXB

I was wondering whether there is a way to create an object such that a list of such object does not need a root element. For example, if I wanted to create an XML like
<Dogs>
<Dog>A</Dog>
<Dog>B</Dog>
<Dog>C</Dog>
</Dogs>
I could have the class Dogs which would be the root element and has a List<Dog>. Now supposed I want to get rid of the encapsulating element <Dogs>. So that the list of dog would look like
<Dog>A</Dog>
<Dog>B</Dog>
<Dog>C</Dog>
how should I construct my classes?
In XML this is not possible. The specification at http://www.w3.org/TR/xml/#NT-document clearly says that a document has one root element.
Your second XML-like code is therefore not an XML document, but a concatenation of three XML documents. But parsers aren't usually prepared for this kind of input.

Mapping Java with JAXB annotations to XSD keys/keyrefs

We are using JAXB to map Java classes into XML files. Currently we use the Java-to-XSD approach by annotating the Java classes.
This works fine in general but we've hit the following problem now: we want an attribute of one XML element to refer to another XML element by it's name/ID. Imagine some XML describing a conceptual schema, with the entities defined in <entity> elements and <property> elements used to establish the links. The #type attribute of the properties should then reference an entity in the same file.
Is it possible to model this using JAXB? What I imagine is having xsd:key and xsd:keyref elements in the schema which should then be resolved to the matching Java objects when unmarshalling.
It's non-trivial, but possible:
http://weblogs.java.net/blog/2005/08/15/pluggable-ididref-handling-jaxb-20

Categories