I am currently trying to unmarshall a xml get response into one intricate java object. That java object has other classes as fields, so it goes very deep. Now, I am using the JaxbMarshaller2 for this job. So far everything has been going well, but now I am have a question:
Basically one of the tags in the XML stream is called "images" and contains an array of individual image items, each enclosed in the "item" tag.
<images>
<item>
<name></name>
</item>
<item>
<name></name>
</item>
</images>
Now, in my root java class, I have a property called images, which is a list of these image items (I made a custom class for these items.)
#XmlElement(name = "images")
private List<ProductImage> images;
Ok, now inside the ProductImage class, would the XML root element above the class name be #XmlRootElement(name="images") or #XmlRootElement(name="item")?
Thanks for your responses.
The #XmlRootElement annotation is only necessary for the root element of your xml file. Each parent always defines the names of the tags of its children. But since the root element has no parent, there is an additional annotation necessary to define its name (i.e. #XmlRootElement).
Option1:
Assuming that the <images> node is your root node of your xml file.
Create a class ProductImageCollection which has the #XmlRootElement(name="images") annotation.
Inside this class there should be a List<ProductImage> which has an annotation #XmlElement(name="image")
Option2:
Assuming that your <images> node is part of a bigger xml structure, which already has correct annotations.
Then you don't need any additional #XmlRootElement annotations. You can directly annotate your list with #XmlElementWrapper(name="images").
Related
I try to use the Alfresco NodeService to make a content node (QName cm:content) the primary parent of another content node. NodeService provides a method
public ChildAssociationRef moveNode(
NodeRef nodeToMoveRef,
NodeRef newParentRef,
QName assocTypeQName,
QName assocQName)
throws InvalidNodeRefException;
Let's say the current primary parent of the node theNodeToMove is a folder and the primary parent assoc reference of the node in the folder is primaryAssocRef. Let theTargetContentNode be the target content node.
Calling the above message like this
nodeService.moveNode(theNodeToMove,
theTargetContentNode,
primaryAssocRef.getTypeQName(),
primaryAssocRef.getQName());
fails. Alfresco reporst an integrity violation:
The association source type is incorrect:
Source Node: workspace://SpacesStore/27a97736-222c-4bac-8610-f15ce312b074
Association: Association[ class=ClassDef[name={http://www.alfresco.org/model/content/1.0}folder], name={http://www.alfresco.org/model/content/1.0}contains, target class={http://www.alfresco.org/model/system/1.0}base, source role=null, target role=null]
Required Source Type: {http://www.alfresco.org/model/content/1.0}folder
Actual Source Type: {http://www.alfresco.org/model/content/1.0}content
Is it even possible to make a content node the primary parent of an existing content node?
Yes and no. Yes because content node can have children, and no because you can't use the "contains" association.
Basically, when you create a "parent-child" relation, you need to state it's association type. You can have as many of these, for instance rm:rendition is one of these types.
The "main" association type used when you create a document under a folder is cm:contains, and is setup in a way that does not allow content nodes to have children. This is done through model definition, and looks something like this:
<type name="cm:folder">
<title>Folder</title>
<parent>cm:cmobject</parent>
<archive>true</archive>
<associations>
<child-association name="cm:contains">
<source>
<mandatory>false</mandatory>
<many>true</many>
</source>
<target>
<class>sys:base</class>
<mandatory>false</mandatory>
<many>true</many>
</target>
<duplicate>false</duplicate>
<propagateTimestamps>true</propagateTimestamps>
</child-association>
</associations>
</type>
In my class, I have more than 80 attributes.
I have to do it into xml file using JAXB using the same order in class.
so please suggest me a propOrder that create automatically or some other way to give in same order as i given in class.
Note:By default i m getting output in alphabetical order
example:
Java object : order[id = 1, item = 121, qty = 10, city = QWE, ..........., addr = ASD]
excepted result : In xml file
<order>
<id>1</id>
<item no>121</item no>
<qty>10</qty>
.
.
.
.
<addr>ASD</addr>
</order>
If you are creating the xml from the Java object then use
#XmlType (propOrder={"id","item",..."addr"})
A similar post talks about is and in more details.
JAXB and property ordering
For additional check
If you are converting xml to Java object you should use sequence element if you are validating via xsd.
http://www.w3schools.com/schema/el_sequence.asp
The order that you specify the fields and properties in your class is not significant. This means that when the JAXB (JSR-222) implementation introspects the class it may not see the fields/properties in the same order that you specified them in. Alphabetical order is the easiest way to offer consistent ordering. If you want to specify an order you need to use propOrder on #XmlType.
I'm using CXF to generate java classes from a WSDL/XSD and later back to XML (for JMS).
In one of the generated classes, it says:
#XmlElement(namespace = "http://www.example.com/", nillable = true)
protected Datum datum;
All good, but when I put a null value:
test.setDatum(null);
I get the following XML generated:
<datum xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
The xsi:nil="true" is what i want, but I don't want the namespace xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance", because this namespace is already specified at the root element. Also the validation fails at the test platform we have to use.
How do I get rid of the extra namespace in the element?
I did it the other way around. I wrote a interceptor that checks for certain attributes. If found, I add the xsi:nil="true" attribute to the xml.
I figure this will be easy for someone who really understands JAXB binding files...
Basic Question
How do you configure JAXB to unmarshal multiple elements into the same class?
Note: I want to avoid adding another dependency to my project (like MOXy). Ideally, this can be accomplished with annotations or a custom bindings file.
Background
I have an XML document that contains lots of variations of the same element--each with the exact same properties. Using my example below, all I care about is "Employees" but the XML specifies "directors, managers and staff." For our purposes, these are all subclasses of the same parent and we only need to work with the parent type (Employee) and our object model doesn't have or need instances of the subclasses.
I want JAXB to bind any instance of director, manager, or staff elements into an Employee object.
Example
input:
<organization>
<director>
<fname>Dan</fname>
<lname>Schman</lname>
</director>
<manager>
<fname>Joe</fname>
<lname>Schmo</lname>
</manager>
<staff>
<fname>Ron</fname>
<lname>Schwan</lname>
</staff>
<staff>
<fname>Jim</fname>
<lname>Schwim</lname>
</staff>
<staff>
<fname>Jon</fname>
<lname>Schwon</lname>
</staff>
</organization>
output:
After unmarshalling this example, I would end up with an Organization object with one property: List<Employees> employees where each employee only has a firstName and lastName.
(Note: each employee would be of type Employee NOT Director/Manager/Staff. Subclass information would be lost when unmarshalling. We also don't care about marshaling back out--we only need to create objects from XML)
Can this be done without extensions like MOXy? Can a custom bindings.xjb file save the day?
This corresponds to a choice structure. You could use an #XmlElements annotation for this use case:
#XmlElements({
#XmlElement(name="director", type=Employee.class),
#XmlElement(name="manager", type=Employee.class)
})
List<Employee> getEmployees() {
return employees;
}
If you are starting from an XML schema the following will help:
http://blog.bdoughan.com/2011/04/xml-schema-to-java-xsd-choice.html
I have a XML format that I want to marshal using JAXB and it looks a bit odd to me. Here is the XML
<root>
<parent>
<child>1</child>
<child>2</child>
<child>10</child>
</parent>
</root>
I want to get the List of child back. Usually if the parent has multiples different child, I would make parent a class, and use #XmlElement to refer to parent from root, but in this case parent only have 1 child, and it repeat multiple times, so it is a bit odd to me. The XML format can be changed.
You could do the following leveraging #XmlElementWrapper:
#XmlRootElement
public class Root {
#XmlElementWrapper(name="parent")
#XmlElement(name="child")
private List<String> children;
}
For More Information
http://blog.bdoughan.com/2010/09/jaxb-collection-properties.html
Have you considered adding List in your Parent class and annotating it with #XmlElement?
#XmlElement
protected List<Child> child;