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

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...

Related

Find out specific element with unique id from json array

I have json array & want to group weeks according to person id's as mentioned in below example. I tried code but unable to get it because i am new to free-marker code. The JSON Array as follows:-
[{"Hours":"5.500","Status":"Draft","Week":"17","person_name":"Raj","person_id":"1414"},
{"Hours":"0.500","Status":"Draft","Week":"17","person_name":"Raj","person_id":"1414"},
{"Hours":"24.500","Status":"Draft","Week":"14","person_name":"Mukesh","person_id":"1046"},
{"Hours":"7.500","Status":"Draft","Week":"15","person_name":"Mukesh","person_id":"1046"},
{"Hours":"3.000","Status":"Draft","Week":"16","person_name":"Mukesh","person_id":"1046"}]
Could please help me. The output in below foramt
for id {1046:[14,15,16], 1414:[17,17]}
Such kind of restructuring is not something that should be done inside a template. While FTL can add together map-like values and also list-like values, it would be very inefficient to hack this together with that (it's only for very simple tasks). The entries should be already grouped before passing the data to the template.
If you must initiate this from the template, then you will need a utility Java object that has a method that does this grouping, or a TemplateMethodModelEx implementation that does it. Then you call that utility object from the template (like utils.groupByPersonId(foo) or groupByPersonId(foo)). Such utility objects can be exposed to the template on various ways: as part of the data-model, globally as "shared variable" through the freemarker.tempalte.Configuration object, or by ensuring that the utility TemplateMethodModelEx (or any other TemplateModel) class is visible for Java and then do something like <#assign groupByPersonId = 'com.example.GroupByPersonIdMethod'?new()> in the template.

How to calculate figure's size including all sub figures (that have separate edit parts) in GEF?

I'm trying to draw diagram that contains a single entity which holds multiple elements inside.
My MVC structure looks something like this:
Model: contains EntityModel.java and ElementModel.java which represents my model objects.
View: EntityFigure.java and ElementFigure.java
Controller: EntityEditPart.java and ElementEditPart.java
I'm overriding getModelChildren() in EntityEditPart.java to return list of ElementModel.java so that is how GEF knows that an element "belongs" to an entity.
Since I would like to calculate my entity's figure size and include the embedded elements in this calculation, I cannot call entityFigure.getPreferredSize() during createFigure() in EntityEditPart.java since at this point - the elements figures do not exists (createFigure() in ElementEditPart.java is not invoked yet).
I'm looking for a place to set my entity figure after all child figures were created.
I though about overriding addNotify() in ElementEditPart.java, however, it is being called after creating a specific inner element and not after all elements created.
Any ideas?
Hope I was clear enough...
You can do it in an extension of
refreshChildren()
method of an edit part, since all the child creation is done in refreshChildren() of superclass's (AbstractEditPart) refresh method:
public void refresh() {
refreshVisuals();
refreshChildren();
}
Or, you can just extend
refresh()

How can I find all elements in an XML Schema whose value is specified as a QName?

Suppose that...
I have a complex XML schema, one that imports/includes other schema files, which in turn import/include even more schema files.
I want to find all the elements in this XML schema that have a value (i.e., text node) that is declared to be of type QName.
I want the location (path) of these elements to be expressed as XPath statements (e.g., /foo/bar).
If I'm writing a Java application, what's the right technology for this job? Is it a schema object model like XSOM? Is it the Java XPath API? Something else?
Edit: For those who want a jumpstart on accessing the SCM in Saxon (per Michael Kay's recommendation below), here's some Java code (sans exception handling):
// Load the XSD into Saxon
Processor processor = new Processor(true);
SchemaManager schemaManager = processor.getSchemaManager();
DocumentBuilder documentBuilder = processor.newDocumentBuilder();
SAXSource saxSource = new SAXSource(new InputSource("path/to/yourSchema.xsd"));
XdmNode schema = documentBuilder.build(saxSource);
schemaManager.load(saxSource);
// Export the SCM
XdmDestination destination = new XdmDestination();
schemaManager.exportComponents(destination);
XdmNode xdmNode = destination.getXdmNode();
System.out.println(xdmNode.toString());
Querying schema documents is a difficult thing to get right, because in XSD there are so many ways of saying the same thing: for example named model groups and attribute groups complicate your task considerably.
If you're looking for types derived from QName as well as QName itself, then it really gets quite difficult.
Doing it on a "compiled" schema of some kind is therefore much easier than doing it on raw schema documents.
Using XSOM is one approach, though it doesn't have a query capability IIRC. Another approach is to use Saxon's SCM output: this is a representation of the compiled "schema component model" in XML form; being the compiled schema you don't have to worry about all the complexities of xs:include, xs:redefine, etc, while being XML means you can use XQuery on it. (I would recommend XQuery rather than XPath because there will be a lot of joins involved, including recursive joins for which you need user-defined functions.)

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

Performance of IQueryable versus Dictionary

I'm caching a whole bunch of static metadata in my app at startup. It's from a db and there are tons of Foreign Key relationships. I'm looking into the best way of modelling them.
I've just started off with LINQ.
It's easy for me to declare a class
public class AllData {
public static IQueryable<libm_ColPurpose> IQ_libm_ColPurpose = libm_ColPurpose.All();
public static IQueryable<libm_ColType> IQ_libm_ColType = libm_ColType.All();
...
(I'm using SubSonic 3 to generate my classes, but that's beside the point).
Then I can use the IQueryable<T> members to get access to anything I want, for example:
libm_ColType ct = AllData.IQ_libm_ColType.SingleOrDefault(x => x.ColTypeStr == this.DefaultJetColTypeStr);
Prior to using IQueryable I was using Dictionaries to store FK relationships, so to mimic the above code I'd code the following from a preexisting List<libm_ColType> list
Dictionary<string, libm_ColType> colTypeByColTypeStr = new Dictionary<string, libm_ColType>();
foreach (libm_ColType x in list) { rtn.Add(x.ColTypeStr, x); }
and then I could use
libm_ColType ct = colTypeByColTypeStr[this.DefaultJetColTypeStr];
OK, so finally we get to the question !
The Dictionary lookup by ID is extremely efficient, however the IQueryable solution is far more flexible and elegant.
I'm wondering how much of a performance hit I'm going to get using IQueryable. I suspect I am doing a linear scan of the list each time I call it, and that's really gonna add up over repeat calls if there are a lot of records involved.
It woul be great if I could identify unique-valued columns and have a hashtable generated and cached after the first lookup, but I suspect this is not gonna be part of the offering.
This is a bit of a dealbreaker for me regarding using LINQ.
Note (I'll repeat it again) that I'm NOT pulling data from a database, it's already in memory and I'm querying it there, so I'm only interesting in looking up the in-memory IQueryable<T>.
IQueryable represents a collection in a data-store, so you probably don't have the collections in memory. If you explicitly want in-memory collections, then I would go back to your dictionaries. Remember, this doesn't prevent you from using LINQ queries over the data.

Resources