I have used JAXB for XML parsing in the past and created my own simple classes for it. Those were POJOs like
public class Foo {
@XmlAttribute
public String someAttribute;
public String someElement;
public Bar bar;
}
Now I want to write a tool that has to parse data from a very complex xml structure and I would like to avoid writing them all by myself. I tried using xjc to generate the classes, but they look entirely different from my example above:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "RulesElementType", propOrder = { "content" })
public class RulesElementType {
@XmlElementRefs({ @XmlElementRef(name = "flavor2", type = JAXBElement.class, required = false),
@XmlElementRef(name = "specific", type = JAXBElement.class, required = false),
@XmlElementRef(name = "category2", type = JAXBElement.class, required = false),
@XmlElementRef(name = "flavor1", type = JAXBElement.class, required = false),
@XmlElementRef(name = "print-prereqs", type = JAXBElement.class, required = false),
@XmlElementRef(name = "prereqs2", type = JAXBElement.class, required = false),
@XmlElementRef(name = "rules", type = JAXBElement.class, required = false),
@XmlElementRef(name = "prereqs1", type = JAXBElement.class, required = false) })
@XmlMixed
protected List<Serializable> content;
@XmlAttribute(name = "name")
protected String name;
@XmlAttribute(name = "type1")
protected String type1;
@XmlAttribute(name = "internal-id")
protected String internalId;
@XmlAttribute(name = "source")
protected String source;
@XmlAttribute(name = "revision-date")
protected String revisionDate;
/* getters and setters omitted */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = { "value" })
public static class Category2 {
@XmlValue
protected String value;
@XmlAttribute(name = "name")
protected String name;
/* getters and setters omitted */
}
/* additional class definitions omitted */
}
To get the element named "flavor1" I have to search the "content" attribute for a JAXBElement named "flavor1" which I find terribly inconvenient. What I would like to be able to do instead is something like:
String flavor1 = rulesElement.getFlavor1();
Is there a way to accomplish this using xjc or another tool?
Edit: The complexType for RulesElementType from my xsd is:
<xs:complexType name="RulesElementType" mixed="true">
<xs:choice maxOccurs="unbounded" minOccurs="0">
<xs:element name="category2">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="name" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="prereqs2">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="name" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element type="xs:string" name="print-prereqs"/>
<xs:element name="flavor2">
<xs:complexType mixed="true">
<xs:choice maxOccurs="unbounded" minOccurs="0">
<xs:element type="grantType" name="grant"/>
<xs:element type="stataddType" name="statadd"/>
<xs:element type="textstringType" name="textstring"/>
<xs:element type="selectType" name="select"/>
<xs:element type="replaceType" name="replace"/>
<xs:element type="modifyType" name="modify"/>
<xs:element type="dropType" name="drop"/>
<xs:element type="suggestType" name="suggest"/>
<xs:element type="stataliasType" name="statalias"/>
</xs:choice>
<xs:attribute type="xs:string" name="name" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element type="specificType" name="specific"/>
<xs:element type="rulesType" name="rules"/>
<xs:element type="xs:string" name="prereqs1"/>
<xs:element name="flavor1">
<xs:complexType mixed="true">
<xs:choice maxOccurs="unbounded" minOccurs="0">
<xs:element type="grantType" name="grant"/>
<xs:element type="stataddType" name="statadd"/>
<xs:element type="textstringType" name="textstring"/>
<xs:element type="selectType" name="select"/>
<xs:element type="replaceType" name="replace"/>
<xs:element type="modifyType" name="modify"/>
<xs:element type="dropType" name="drop"/>
<xs:element type="suggestType" name="suggest"/>
<xs:element type="stataliasType" name="statalias"/>
</xs:choice>
<xs:attribute type="xs:string" name="name" use="optional"/>
</xs:complexType>
</xs:element>
</xs:choice>
<xs:attribute type="xs:string" name="name" use="optional"/>
<xs:attribute type="xs:string" name="type1" use="optional"/>
<xs:attribute type="xs:string" name="internal-id" use="optional"/>
<xs:attribute type="xs:string" name="source" use="optional"/>
<xs:attribute type="xs:string" name="revision-date" use="optional"/>
</xs:complexType>
The XML file looks somewhat similar to this.
I use XMLBeans to generate the xsd. Since the XML file I am reading from has about 680k lines, manually creating the XSD is not an option.
You can use the Simplify plugin to simplify your content property.
SO disclaimer: I'm the author.
Please see this questions:
Generate java classes from xsd with jaxb from a choice
extracting element text value
In short, if you use this plugin and customize one of the elements which go into your content property with simplify:as-element-property, you can get distinct easy to use element properties per element. I hope this is what you mean with "pretty".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With