EclipseLink MOXy #XmlPath support for axes/parent - xpath

Are any of the following XPath expressions acceptable? Using version 2.3.1 of eclipselink
#XmlPath("../header/#type")
#XmlPath("/root/header/#type")
#XmlPath("parent::*/header/#type")
Basically this is in a class which repeats within the XML document (/root/tag), if that isn't clear I'll elaborate.
I'm trying to traverse up the tree rather than down. My other #XmlPath annotations are working fine.

EclipseLink JAXB (MOXy) does currently not support axes/parent. If you are interested in this kind of support please enter an enhancement request:
https://bugs.eclipse.org/bugs/enter_bug.cgi?product=EclipseLink
It does support XPath like:
#XmlPath(".") // Map to self node, useful when mapping two objects to same element
#XmlPath("#foo") // Map to attribute
#XmlPath("foo") // Map to element
#XmlPath("foo[2]") // Map to 2nd occurence of
#XmlPath("foo[#bar='Hello World']") // Map to foo element with bar attribute with value "Hello World"
#XmlPath("ns1:foo/ns2:#bar") // Map to namespace qualified nodes
For More Information
http://blog.bdoughan.com/2010/07/xpath-based-mapping.html
http://blog.bdoughan.com/2010/09/xpath-based-mapping-geocode-example.html
http://blog.bdoughan.com/2011/03/map-to-element-based-on-attribute-value.html

Related

Can not get number of xml nodes from document using spring integration

I am attempting to get the count of the //Root/Record elements using spring integrations int-xml:xpath-header-enricher. It comes back zero regardless of the document passed in.
You have to configure your XPath expression like this:
<int-xml:xpath-expression id="countExpression" expression="count(//ns:Ephemeris/ns:Record)"
ns-prefix="ns"
ns-uri="http://www.sandia.gov/pgmm/Ephemeris"/>
And have it as a reference from the <int-xml:header> instead.
The problem is that your root element in the XML comes with the xmlns="http://www.sandia.gov/pgmm/Ephemeris", so, there is no other way unless we honor namespaces in your source XML. For this purpose we introduce artificial prefix, even if your source XML does have then. We need that in XPath to properly distinguish elements based on some namespace.
I think default DocumentBuilderFactory just doesn't honor namespaces making your possible XPath expressions much horrible when it comes to several namespaces support.

How to bind Maps of Maps, or some other way to structure the data

I am not even sure how to go about asking this, but I will try to give it a shot.
I have an existing application that I support that consists of a dynamically generated form of a bunch of values. The form is broken into a matrix of rows and columns, and the JSP uses this information to construct the required form:inputs. To build the form I have some Java classes like such (mostly pseudo code just so you get an idea as to what I am doing):
class Form {
List<FormParts> parts;
}
class FormParts {
List<FormRow> rows;
List<FormHeader> headers;
}
class FormRow {
String name;
}
class FormHeader {
String name;
}
I use these classes to dynamically build the form in the JSP by looping through the FormParts, then using the FormRows and FormHeaders to build a table of form:inputs, using a counter to index the resulting answers List described here in the FormResponse:
class FormResponse {
List<FormAnswer> answers;
}
class FormAnswer {
int rowNumber;
int headerNumber;
String value;
}
The problem I am having is the List<FormAnswer> answers. Because it's a List I have to store all the Answers, even the empty ones (nulls), in order to be able to provide the ability to reload the FormResponses from the DB. This is creating a HUGE amount of junk rows in my table, and making the application slow. When I first wrote this about 4 months ago, however, I remember I struggled for some time trying to figure out how to make Spring MVC bind to a Map of Maps, which would be a MUCH better way to implement this since I could simply skip the answers I don't need. I remember the problem was that, internally in Spring MVC, those Lists and Maps become LazyList and LazyMap.
Does anyone have another possible solution to this?
Check my answer on dynamic forms with Spring here at Auto populating Set .
The key is to use Map<Integer, YourObject> instead of lists. With that you can have gaps in your indexes.
Using Map of Maps is not possible, because the generics will be erased. The map always need to be property of object. So your example should be OK.
Concept of LazyList / LazyMap is long dead. Spring is capable of manipulating any list and map type. If the Map property is null, an instance of LinkedHashMap is created by default.
Other possibility is to do your binding and validation manually and just send JSON via the wire (i.e. submit your form as JSON in <input type="hidden"> or directly via AJAX).

Validate a java.util.Map against a XML schema (No XML document only a Map Object)

This may be a weird question, but recently i am thinking of something like validating a map object having key- value pairs from an xsd. I mean if xsd have a two elements like foo and bar under some root element and a map contains key - value pairs like foo = "me" and bar = 123, i should be able to validate this map against corresponding xsd without transforming the map into xml/json or anything model sort of thing. i have done some search but couldnt find any api supporting this. Also i looked into javax.xml.validation api but i couldnt figure out that how exactly the Validator validates the xml against xsd. If somehow i can get properties of each element from the xsd and then maybe i will be able to validate the map. Please give me some information regarding this, any suggestion is welcomed.

eclipselink moxy xpath - selecting all child elements of the current node or all elements in a document with a particular name

i have this xpath defined for moxy in a jaxb class
#XmlPath("child::*/REG")
public List entries;
but it won't unmarshal the xml document correctly. the List variable called entries is empty.
i've also tried
#XmlPath("*/REG")
public List entries;
i've also tried
#XmlPath("//REG")
public List entries;
without joy
but if i do
#XmlPath("BANKGIRO/REG")
public List entries;
it's fine and the list is populated.
I haven't looked through the source yet but I'm guessing this type of xpath is not supported yet. I checked all my xpath in an xpath verifier for sanity and all the xpath above is fine (all the xpath is valid for the context node i'm positioned at).
EclipseLink JAXB (MOXy) does currently not support an XPath like: #XmlPath("child::*/REG"). Our focus has been on supporting XPath statements that provide enough information for marshalling as well as unmarshalling. For example it is clear what #XmlPath("child::*/REG") means on a read, but is ambiguous in terms when writing that object back to XML or JSON. If you are interested in this kind of support please enter an enhancement request:
https://bugs.eclipse.org/bugs/enter_bug.cgi?product=EclipseLink
MOXy does support XPath like:
#XmlPath(".") // Map to self node, useful when mapping two objects to same element
#XmlPath("#foo") // Map to attribute
#XmlPath("foo") // Map to element
#XmlPath("foo[2]") // Map to 2nd occurence of
#XmlPath("foo[#bar='Hello World']") // Map to foo element with bar attribute with value "Hello World"
#XmlPath("ns1:foo/ns2:#bar") // Map to namespace qualified nodes
For More Information
http://blog.bdoughan.com/2010/07/xpath-based-mapping.html
http://blog.bdoughan.com/2010/09/xpath-based-mapping-geocode-example.html
http://blog.bdoughan.com/2011/03/map-to-element-based-on-attribute-value.html

How can I extract a part of a xaml object graph via linq to xml?

I have an object graph serialized to xaml. A rough sample of what it looks like is:
<MyObject xmlns.... >
<MyObject.TheCollection>
<PolymorphicObjectOne .../>
<HiImPolymorphic ... />
</MyObject.TheCollection>
</MyObject>
I want to use Linq to XML in order to extract the serialized objects within the TheCollection.
Note: MyObject may be named differently at runtime; I'm interested in any object that implements the same interface, which has a public collection called TheCollection that contains types of IPolymorphicLol.
The only things I know at runtime are the depth at which I will find the collection and that the collection element is named ``*.TheCollection`. Everything else will change.
The xml will be retrieved from a database using Linq; if I could combine both queries so instead of getting the entire serialized graph and then extracting the collection objects I would just get back the collection that would be sweet.
Will,
It is not possible to find out whether an object implements some interface by looking at XAML.
With constraints given you can find xml element that has a child named .
You can use following code:
It will return all elements having child element which name ends with .TheCollection
static IEnumerable<XElement> FindElement(XElement root)
{
foreach (var element in root.Elements())
{
if (element.Name.LocalName.EndsWith(".TheCollection"))
{
yield return element.Parent;
}
foreach (var subElement in FindElement(element))
{
yield return subElement;
}
}
}
To make sure that object represented by this element implements some interface you need to read metadata from your assemblies. I would recommend you to use Mono.Cecil framework to analyze types in your assemblies without using reflection.
#aku
Yes, I know that xaml doesn't include any indication of base types or interfaces. But I do know the interface of the root objects, and the interface that the collection holds, at compile time.
The serialized graphs are stored in a sql database as XML, and we're using linq to retrieve them as XElements. Currently, along with your solution, we are limited to deserializing the graphs, iterating through them, pulling out the objects we want from the collection, removing all references to them from, and then disposing, their parents. Its all very kludgy. I was hoping for a single stroke solution; something along the lines of an xpath, but inline with our linq to sql query that returns just the elements we're looking for...

Resources