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.
Related
I am looking for an extension of doc() functionality currently available in SAXON in a way that it will read XML not from filesystem or from http network, but from memory, where I have those xmls.
The way I want to use it is like:
mydoc('id')/root/subroot/#myattr
or
doc('mydoc://id')/root/subroot/#myattr
What I have considered so far:
use queryEvaluator.setContextItem() - does not solve my use case as I can have multiple XML sources in one query
register some own URL scheme protocol into Java - seems to me like overkill and I have never done this
write own ExtensionFunction - seems to be the right way so far, but i am confused whether I should use ExtensionFunction or rather ExtensionFunctionDefinition. Also I am littel bit confused by Doc_1 and Doc Saxonica source code as it uses Atomizer and other unknown internall stuff.
So the questions are:
Is it variant 3 the best one (in the means of simplicity) or would you recommend some other approach ?
Is it OK to use ExtensionFunction and return XdmNode from my in-memory xmls ? It seems to me it should work, but I really do not want to step into some edge cases or saxon minefield.
Any comment from experienced Saxon user will be appretiated.
The standard way of doing this is to write a URIResolver and register it with the transformer. The URIResolver is called, supplying the requested URI, and it is expected to return a Source (which can be a StreamSource, SAXSource, or DOMSource, for example). In this scenario you would typically return a StreamSource wrapping a StringReader which wraps the String containing the XML.
You could equally well use an extension function, but it's probably a little bit more complicated.
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.
I know that I can compile multiple xsd files in a single jar. I've tried using different namespaces which only takes me half way through my goal. This way I can parse the correct schema but I want this to be transparent to my users which will receive the xmlBeans object that I've parsed.
They don't have to know which version of xml file is currently present on the system. I would need a super class for every xsd version to achieve this.
Could this be done with xmlBeans?
My understanding is, if you have a com namespace and a com.v1 and com.v2 namespace and you have an xsd element called EmployeeV1 in com.v1 and EmployeeV2 in com.v2.
You want to a super class called Employee in the com namespace which you want to return to your caller?
Do you think EmployeeV1 and EmployeeV2 could extend from Employee in your xsd? Then maybe when you generate you will get the class hierarchy that represents your xsd.
If that doesn't work, (i haven't used xmlbeans in years now), you might have to create your own domain object and make your callers consume that. That might be worth the effort, since to me it looks like you handle the parsing of an XML that other people rely on, you could abstract all other users from the structure of the XML (which is in flux) by having an intermediary domain object.
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.
Need to serialize java objects to JSON while doing compression such as name change, exclusion etc. Objects use class from jar, source code of which is not available.
Looked through many libraries(Jackson , Gson), but found none solving this particular problem. Most of them are annotations based, which I can't use given I don't have source code.
One way to solve this problems is, use reflection and recursively go through object until you find a property name of which should be replaced or object is excluded in serialized JSON.
Need solution for this. Better if it is already implemented and tested.
You can also have a look at Genson library http://code.google.com/p/genson/.
You can rename and filter with quite concise code:
// renames all "fieldOfName" to "toName", excludes from serialization
// and deserialization fields named "fieldNamed" and declared in DefinedInClass
// and uses fields with all visibility (protected, private, etc)
Genson genson = new Genson.Builder().rename("fieldOfName", "toName")
.exclude("fieldNamed", DefinedInClass.class)
.setFieldFilter(VisibilityFilter.ALL)
.create();
genson.serialize(myObject);
If you want to do some more complex filtering (based on annotations for example) you can implement BeanMutatorAccessorResolver or extend BaseResolver.
Same for property renaming you can implement PropertyNameResolver and have full control.
And finally if you want to filter fields, methods or constructors according to their modifiers you can define your own VisiblityFilter.
Concerning performances of filtering/renaming there should be no problem as it is done only once per class and then cached.
To start using Genson you can have a look at the Getting Started Guide.
Found solution to the problem.
Google gson has class called GsonBuilder which has methods for exclusion strategy and naming strategy.
Using these two methods implemented a custom solution, where all the mapping and exclusion rules are stored using a xml and used at the time of serialization and de-serialization.
Works perfectly, though not sure about the performance of same.