Thursday, May 31, 2007
Tuesday, May 29, 2007
Passing xml between xsl and a helper method
In that, I'm also quite frequently using helper classes in assemblies called directly from the xsl, on which I have posted before.
Mostly I'm passing simple values between the two such as strings and ints, but every now and then I need to pass a whole xml struture between them - it might be a node-set from the xsl that needs to be processed by the helper method, it might be that the method returns an xml fragment the xsl needs to then iterate on or, most likely, it will be both.
The way to do it is quite simply to use the XPathNodeIterator class in the System.Xml.XPath namespace.
I did not know about this class until I had to do this bit, so it has to be worth posting (for myself if not for anyone else).
To demonstrate it's use I've create a helper method as follwos -
public XPathNodeIterator processXml(XPathNodeIterator nodeset)
XPathNavigator nav = nodeset.Current;
XPathNodeIterator i = nav.Select("//*");
As you can see this method doesn't really do much, but it already demonstrates how to receive an xml node-set and how to return one.
the helper method can work with the following xsl -
<xsl:variable name="MyNodeSet" select="<some xpath>"/>
<xsl:variable name="HelperResult" select="helpers:processXml($MyNodeSet)"/>
<xsl:value-of select="$HelperResult/<some other xpath>"/>
The next challange was how to create a brand new XPathNodeIterator, here's one way (assuming xmlDoc is an XmlDocument that contains the xml you need to return -
xPathNav = xmlDoc.CreateNavigator();
XPathExpression xPathExpr = xPathNav.Compile("
XPathNodeIterator xPathNodI = xPathNav.Select(xPathExpr);
No problem, we thought, as the 2006 version of bm.exe has this shiny new update-all feature that would solve all of our problems.
Either we or MS missed something big-time (and as much as I'd like to think it's not me I do realise most chances are that it is, so plese do correct me if I'm wrong) -
Our first attempt was very naive - we've simply opened our bam excel spreadsheet, added the activity item to the activity, updated the view we had to include the added field, saved the spreadsheet and used bm.exe update-all -definitionFile:
Only that instead we got the following error:
At first we thought - DUH! - of course it is different - we just changed it! isn't that the whole point of update-all??
but further playing around revealed that the main point in that error is the word view - while bm.exe will quite happily add items to activities it is not at all happy to update views (I'm guessing the difference lies in the difference between add and udpate, but I'm not at all sure).
To prove this, we went back to the spreadsheet and manually returned the view to it's previous state - the one before we added the extra field; the activity still had the additional item though.
We re-executed bm.exe as before and this time it worked liked a charm. the new field was added to the activity (with all values being null, of course). the view, as you can expect, did not change.
This is good news as we can indeed add fields to our activities, but this is only half the solution as we can't update the views to see them; I don't know of any other way to update the views, surely there must be some solution other then mofifying them by hand? and so - as I've said - either I've missed something big time or MS has.
I found a newsgroups thread in which Ekta Aggarwal [MSFT] suggests deploying the view with a different name, which does work, but, at least in our case, changes everything that uses that view which is less than ideal to say the least (as well as leaving a trail of unwanted views that now have to be removed).
BTW - I'm not sure how this will work in conjuntion with archiving, but already I've spotted a further challange once the data has been partitioned -
if you run the DTS/SSIS job that partitiones the completed tables, and then try to update an activity you get a different error:
All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.
I suspect this is because an attempt is made to modify the tables while the views have a union to the partitioned versions.
The only way to overcome this (I think) is to manually remove the union from the views first, update the activity using bm.exe and then re-add the union making sure to add the extra field but this is much more manual editing of the views than I would like to do.
Friday, May 25, 2007
Moving to Team Foundation Server
The process went reasonabily smooth from my perspective (largely due to the fact the Jeremy did all of the work while I was away on holiday :-) )
We did however, encounter two mostly unexplained problems post-migration that are worth mentioning.
Although I don't actually understand the cause of the problems, as we've found solutions that worked for us I figured it might be useful to somebody if I post them:
The first type of problem we've had, repeated over several projects and solutions is that for some reasons VS would fail to find a project file in a folder althoguh it clearly exists in the path specified in the error message. because the project cannot be found it from VS perspecive it appears as unloaded in the solution explorer and we could not build properly.
As we could succesfully add the project to another solution we realised the problem is not in the project itself, but scanning the solution file we did not spot anything useful.
The problem was solved by deleting the .sou file created for this solution and letting TFS (or VS) re-generate it.
The second problem we've had is that when we tried to build a project on one of the machines (mine, incidently) we'd get an access denied error when VS tried to create assemblyInfo.cs.
I'm not sure why it tried to re-create it when one already existed, or why the case of the file already existing is not handled, this has to be a bug in VS, but deleting the file and letting VS re-create it solved this problem as well.
far from being the discoveries of the century, but hopefully someone will find this post useful. I'm sure I will a few weeks from now when I encounter this again and forget what it was that I did to solve it!