How can I covert a an xml file to a simple java bean?
Its a simple xml file without any xsd, which was generated from a java bean, which I don't have access to.
I tried using xmlbeans to first generate the xmd from xml and then to generate classes from the xsd. I got a bunch of classes. I am looking for a single java bean class.
JAXB
JAXB (JSR-222) provides an easy way to convert objects to XML. There are many open source implementations of this standard including:
Metro JAXB (the reference implementation included in Java SE 6)
EclipseLink JAXB (MOXy), I'm the tech lead
Apache JaxMe
JAXB has a default mapping for Java objects to XML. This mapping can be customized through the application of annotations.
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.Element;
#XmlRootElement
public class Address {
private String street;
private String city;
private String state;
private String country;
#XmlElement(name="postal-code")
private String postalCode;
}
Would correspond to the following XML:
<address>
<street>123 A Street</street>
<city>Any Town</city>
<state>A State</state>
<postal-code>12345</postal-code>
</address>
EclipseLink JAXB (MOXy)
MOXy has an XPath based mapping extension. This means we can take our same Address class and map it to Google's geocode format:
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.eclipse.persistence.oxm.annotations.XmlPath;
#XmlRootElement(name="kml")
#XmlType(propOrder={"country", "state", "city", "street", "postalCode"})
public class Address {
#XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:SubAdministrativeArea/ns:Locality/ns:Thoroughfare/ns:ThoroughfareName/text()")
private String street;
#XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:SubAdministrativeArea/ns:Locality/ns:LocalityName/text()")
private String city;
#XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:AdministrativeAreaName/text()")
private String state;
#XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:CountryNameCode/text()")
private String country;
#XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:SubAdministrativeArea/ns:Locality/ns:PostalCode/ns:PostalCodeNumber/text()")
private String postalCode;
}
The above class corresponds to the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0" xmlns:ns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
<Response>
<Placemark>
<ns:AddressDetails>
<ns:Country>
<ns:CountryNameCode>US</ns:CountryNameCode>
<ns:AdministrativeArea>
<ns:AdministrativeAreaName>CA</ns:AdministrativeAreaName>
<ns:SubAdministrativeArea>
<ns:Locality>
<ns:LocalityName>Mountain View</ns:LocalityName>
<ns:Thoroughfare>
<ns:ThoroughfareName>1600 Amphitheatre Pkwy</ns:ThoroughfareName>
</ns:Thoroughfare>
<ns:PostalCode>
<ns:PostalCodeNumber>94043</ns:PostalCodeNumber>
</ns:PostalCode>
</ns:Locality>
</ns:SubAdministrativeArea>
</ns:AdministrativeArea>
</ns:Country>
</ns:AddressDetails>
</Placemark>
</Response>
</kml>
For more Information
XPath Based Mapping - Geocode Example
Map to Element based on an Attribute Value with EclipseLink JAXB (MOXy)
XPath Based Mapping
Try Castor Mapping.
You could use a tool like Castor or JAXB to map the XML to a java class. Castor is fairly easy to use.
Related
I am trying to define XML from Java object binding using JAXB. Everything works fine except i want to have currency tag with xml tag like this
<money currency="INR">1230</money>
I am not able to find the solution for this how can i accomadate **currency="INR" ** in the same tag
#XmlElement(name="money")
private Integer money;
Saw that #xmlElement doesnt has any properties for the same
I'm currently trying to get xmlns value. I need to validate xml files. I'm using Jackson-dataformat-xml to deserialize xml files to objects. So far I've not found a way to get that value.
#JacksonXmlProperty(isAttribute = true) does not seem to be working for xmlns.
xml
<Document xmlns="urn:...">
...
</Document>
Java
#Data
public class Document {
#JacksonXmlProperty(isAttribute = true)
private String xmlns;
}
As I understand xmlns isn't exposed as a attribute. Is there any I could get the value somehow with Jackson?
xmlns value is namespace declarations. it's not a attributes but metadata, so parsers do not expose them as attributes.
I have the following xml:
<parameters>
<parameter >value1</param>
<parameter >value2</param>
</parameters>
with the following class:
#XmlRootElement
public class Parameters {
#XmlElement public String parameter;
}
How can I get warned (exception?) of the duplicate values when unmarshaling the xml to object?
You should have a schema a make a schema validation. If your schema permits duplicates then maybe you should switch from String to a Collection type.
If you don't have a schema, you could use schemagen tool to generate it from your java classes.
You could even generate a schema at runtime, maybe cache it together with the JaxbContext and then use it for validation.
I am trying to use the CycleRecoverable interface to manage cyclic issues in my object model for bi-directional relationships. Guides such as this and this, tell you to use CycleRecoverable, but I don't have it on my class path. I'm confused as to what I actually need, and an explanation as to why I need it. I am not using Maven, so I can't follow the second links advice, and even if I was using Maven, I don't understand why I need more packages in order to use JAXB which I thought was included in SE6. What jar files do I actually need to include to use this interface and why? The only CycleRecoverable on my classpath is com.sun.xml.internal.bind.CycleRecoverable
The (un)official JAXB guide notates the interface, but makes no mention of how to actually use it
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.
As an alternative to the CycleRecoverable mechanism in the JAXB reference implementation you may be interested in the #XmlInverseReference extension in MOXy:
Customer
import javax.persistence.*;
#Entity
public class Customer {
#Id
private long id;
#OneToOne(mappedBy="customer", cascade={CascadeType.ALL})
private Address address;
}
Address
The #XmlInverseReference annotation specifies the field name that maps the other direction of this relationship. This is similar to how bidirectional relationships are mapped in JPA.
import javax.persistence.*;
import org.eclipse.persistence.oxm.annotations.*;
#Entity
public class Address implements Serializable {
#Id
private long id;
#OneToOne
#JoinColumn(name="ID")
#MapsId
#XmlInverseReference(mappedBy="address")
private Customer customer;
}
For More Information
http://blog.bdoughan.com/2010/07/jpa-entities-to-xml-bidirectional.html
http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
I'm looking for best tool/way to create and load JAVA objects from XML definitions.
I had checked out JAXB, seems pretty nice, but didn't find is there a way to work with Entities which properties are dynamic, or changed from time to time, so want to have something like automatic way of working with entities, without converting Object into predefine Entity object. Does something like that exists?
Workflow would be like this read from XML create class for each Entity with dynamic set of attributes and/or create ORM mapping part for those entities and then all manipulation retrieve/store into db or probably will going to use some NoSQL solution like MongoDB.
Note: I'm the EclipseLink JAXB (MOXy) lead, and a member of the JAXB 2 (JSR-222) expert group.
Check out the following EclipseLink example. It demonstrates how to use dynamic properties with both the JPA and JAXB implementations:
http://wiki.eclipse.org/EclipseLink/Examples/MySports
Option #1 - Static Objects with Dynamic Properties
MOXy has an #XmlVirtualAccessMethods extension which allows you to map entries in a map to XML. This allows you to add properties to a static class. In the example below the Customer class has a "real" name property and may have many "virtual" properties.
package blog.metadatasource.refresh;
import java.util.*;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlVirtualAccessMethods;
#XmlRootElement
#XmlType(propOrder={"firstName", "lastName", "address"})
#XmlVirtualAccessMethods
public class Customer {
private String name;
private Map<String, Object> extensions = new HashMap<String, Object>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object get(String key) {
return extensions.get(key);
}
public void set(String key, Object value) {
extensions.put(key, value);
}
}
The virtual properties are defined via MOXy's XML metadata. In the example below we will add two properties: middleName and shippingAddress.
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="blog.metadatasource.refresh">
<java-types>
<java-type name="Customer">
<java-attributes>
<xml-element
java-attribute="middleName"
name="middle-name"
type="java.lang.String"/>
<xml-element
java-attribute="shippingAddress"
name="shipping-address"
type="blog.metadatasource.multiple.Address"/>
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
For More Information
http://blog.bdoughan.com/2011/06/extensible-models-with-eclipselink-jaxb.html
http://blog.bdoughan.com/2011/06/moxy-extensible-models-multi-tenant.html
http://blog.bdoughan.com/2011/06/moxy-extensible-models-multiple.html
http://blog.bdoughan.com/2011/06/moxy-extensible-models-refresh-example.html
Option #2 - Dynamic Objects
MOXy also offers full dynamic object models:
DynamicJAXBContext jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(xsdInputStream, null, null, null);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
DynamicEntity customer = (DynamicEntity) unmarshaller.unmarshal(inputStream);
DynamicEntity address = jaxbContext.newDynamicEntity("org.example.Address");
address.set(street, "123 A Street");
address.set(city, "Any Town");
customer.set("address", address);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.marshal(customer, System.out);
For More Information
http://wiki.eclipse.org/EclipseLink/UserGuide/MOXy
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/Dynamic
So, you're basically trying to make POJO's (plain old Java objects) using XML files? They are just like data classes, right?
I'm a big fan of XStream, which is really easy to use and works great if you don't need validation. I've used Castor when validation against a schema was required. I just used XStream to save an object to an xml file and then I can read it back in from anywhere, even if I change the data values associated with the object (which I think is what you mean by "dynamic set of attributes", right?).