Map JAXB generated Objects using XPATH - java

I would like to map the value using Xpath instead of directly accessing the Classname.methodname Using JAXB
eg:
Customer/name
ideal jaxb : new Customer().setName("XXXX");
instead of above : xxxx.setValue("customer/name","XXXXX") should automatically set the value for the Xpath. and generate in the XML .
Is there any provision like this in JAXB. ( I know this in castor using FieldDescriptors and ClassDescriptors).

As far I know there is no provison in JAXB to do this. It's primary purpose is to
Marshall and Unmarshall XML Documents to/from Java Objects.

If I understand you correctly, JAXB is irrelevanto to what you want to do; if you can handle the expressions not being XPATH, have a look into Apache Beanutils: specifically BeanUtils.setProperty(object, "customer.name", "XXXX").

If you are wiling to use another technology, JXPath can be used to navigate javabeans via something similar to xpaths. You can also use JXPath to poplulate javabeans with information
http://commons.apache.org/proper/commons-jxpath/
Specifically, when you supply a factory you can create objects. There are several situations that are not supported nativly, but with a little bit of thought you can implement your own extension of createPathAndSetValue that can deal with your specific predicate logic.
http://commons.apache.org/proper/commons-jxpath/users-guide.html#Creating_Objects

Related

Java XML: How to force wildcard (xs:any) strict matching?

I have a bunch of external XSDs which I can't change.
They use wildcard content models (xs:any) with processContents="skip".
Question:
Is there a programmatic way in java/JAXP to force wildcard (xs:any) processContents="strict" matching instead (without changing the XSDs)?
Sure. Use Java to modify the schema before using it for validation. You don't have to change the original schema, just the one that you're validating against.
If you're using XSD 1.1 you could create the locally-modified schema using xs:override.

JAXB issue with missing namespace definition

So I searched around quite a bit for a solution to this particular issue and I am hoping someone can point me in a good direction.
We are receiving data as XML, and we only have XSD to validate the data. So I used JAXB to generate the Java classes. When I went to unmarshal a sample XML, I found that some attribute values are missing. It turns out that the schema expects those attributes to be QName, but the data provider didn't define the prefix in the XML.
For instance, one XML attribute value is "repository:<uuid>", but the namespace prefix "repository" is never defined in the dataset. (Never mind the provider's best practices suggest defining it!)
So when I went to unmarshal a sample set, the QName attributes with the specified prefix ("repository" in my sample above) are NULL! So it looks like JAXB is "throwing out" those attribute QName values which have undefined namespace prefix. I am surprised that it doesn't preserve even the local name.
Ideally, I would like to maintain the value as is, but it looks like I can't map the QName to a String at binding time (Schema to Java).
I tried "manually" inserting a namespace definition to the XML and it works like a charm. What would be the least complicated method to do this?
Is there a way to "insert" namespace mapping/definition at runtime? Or define it "globally" at binding time?
The simplest would be to use strings instead of QName. You can use the javaType customization to achieve this.
If you want to add prefix/namespace mappings in the runtime, there are quite a few ways to do it:
Similar to above, you could provide your own QName converter which would consider your prefixes.
You can put a SAX or StAX filter in between and declare additional prefixes in the startDocument.
What you actually need is to add your prefix mappings into the UnmarshallingContext.environmentNamespaceContext. I've checked the source code but could not find a direct and easy way to do it.
I personally would implement a SAX/StAX filter to "preprocess" your XML on the event level.

FasterXML Issues while marsahaling to XML

I am trying to marsahall Objects to XML using jackson-dataformat-xml and woodstax but its adding additional namespace prefix wstxns1. Any suggestions ?
My Beans look like as below
#JacksonRootElement(localname="Blah" namespace="http://something"
Bla {
#JacksonXMLProperty(localname="SomeProperty" namespace="http://something"
String SomePropety;
#JacksonXMLProperty(localname="SomeClass" namespace="http://something-different"
Class SomeClass;
....
I assume that you want one of following:
Define "default namespace" (one with no prefix) to bind to URI for element, to avoid prefix -- this is only possible for a single namespace at a time. OR,
Make Woodstox use some other base for prefixes it generates as needed
You would like to offer suggestion for prefix to use (since Stax XMLStreamWriter allows this).
Jackson XML module does not have mechanisms for handling prefixes at this point (although RFEs and pull requests are welcome).
But Woodstox itself has fair bit of configurability, beyond basic Stax API (which is quite limited).
The places to look beyond (documentation, blogs) for additional configuration properties for output are classes:
org.codehaus.stax2.XMLOutputFactory2 for Stax2 extension properties (implemented by Woodstox and Aalto)
com.ctc.wstx.api.WstxOutputProperties for Woodstox-specific properties
and these properties are set via XMLOutputFactory.setProperty(), same as standard Stax properties.
Property of interest here would be org.codehaus.stax2.XMLOutputFactory2#P_AUTOMATIC_NS_PREFIX, which defaults to "wstxns" but can be changed to any other valid XML id String.
Beyond this, it may be possible to specify pre-configured XMLStreamWriter for Jackson XML module to use. If so, it would also be possible to use standard Stax method ("writeNamespace()" I think?) to create specific prefix-to-URL namespace bindings.
Finally, Jackson mailing lists are the best place to ask questions. Developers like myself do read StackOverflow and other forums as well, but latency tends to be higher as you have noticed.

Decoupling XML parser from classes

I'm writing an Android application and I want to provide the ability for the end user to create collections of objects from a class hierarchy with XML. For example: I'd like the user to be able to provide something like this arbitrary example:
<animals>
<dogs>
<bulldog name="Frank" />
<mastif name="George" />
</dogs>
<cats>
<mainecoon name="Alex" age="3" />
</cats>
</animals>
I'd like to validate this user-provided XML against a schema I create, and then create instances of these classes based on the XML. The question I have is that if I add a subclass.. say reptile, I have to change the implementation for the XML parser as well as the schema to validate the XML. This seems like bad practice because a change in the class hierarchy mandates a change in other places. Is there anyway to minimize the impact of adding a type to my Android app with regard to the XML the user can provide and the Schema that validates it?
I found a solution. Using annotations and a framework like JAXB or Simple will let you serialize/deserialize objects to/from xml. JAXB can be run on Android which could be a solution. link
But JAXB is pretty heavy weight so I'm favoring Simple because it is more lightweight.

JAXB 2.0 Validation Question

While working with JAXB 2.0 i came across a query which i am unable to solve so far,while doing the validation i have 2 options
1) Either as soon as i found the error throw the exception as i am done.
2) Move ahead if there is any error or validation and i assume this is the best way since it will help one to show all errors or warings with respect to the whole XML.
but since this process also invlolves unmarshalling means it will unmarshall my provided XML is to respected Object even if there is any Error or warning.so all means extra work..
My question is is these a way so that i can do whole validation and if it is successfull only than should the corresponding XML be bind to respected POJO classes
thanks in advance
You can use the javax.xml.validation APIs to validate an XML document against an XML schema. The you can choose to unmarshal this object again using JAXB.
Below is an example of using these APIs. In this example the input is actually an object model, but you can adapt it to work with any XML input.
http://bdoughan.blogspot.com/2010/11/validate-jaxb-object-model-with-xml.html

Categories

Resources