-
I want my ICodeParser implementation!
-
Note: this entry has moved.
For some reason both the VBCodeProvider and CSharpCodeProvider don't return a valid IParser implementation when asked for through the GetParser() method. I know many argue that CodeDom was not intended for that, that certain language features are not expressible in CodeDom, etc... but, if Boland C#Builder makes it available(find the word IOTACodeDomProvider), I can't see why VS.NET developers can't have it.
Let me say that again: we NEED that feature, as it makes possible refactoring classes, generating code, enforcing coding standards and MUCH more. And please don't point me to the ugly-old-.NET unfriendly EnvDTE.Code* code model. I've learned CodeDom for other new features, I want to use it to manage project items too!
-
Merging XML
-
Note: this entry has moved.
Sometimes, it's useful to be able to merge two XML nodes/documents. One concrete case is where you have a configuration file where some global element is configured and later it can be specialized by concrete usages. There are other uses too, such as consolidating information from various sources, etc. I "found" a way to do this, "stealing" Oliver Becker's XSLT stylesheet and writing the following .NET class that takes advantage of it:
/// <summary>
/// Merges two <see cref="XmlNode"/> objects.
/// </summary>
public class XmlMerge
{
const string First = "first";
const string Second = "second";
static XslTransform Transformation;
static IXPathNavigable Input;
static XmlMerge()
{
Transformation = new XslTransform();
Transformation.Load( new XmlTextReader(
Assembly.GetExecutingAssembly().GetManifestResourceStream(
"XmlMerger.merge.xslt") ),
null, null);
// Dummy input document for the merge stylesheet.
Input = new XPathDocument( new StringReader ( String.Format(
@"<?xml version='1.0'?>
<merge xmlns='http://informatik.hu-berlin.de/merge'>
<file1>mem://{0}</file1>
<file2>mem://{1}</file2>
</merge>", First, Second ) ) );
}
private XmlMerge() {}
/// <summary>
/// Merges the first XML with the second.
/// </summary>
/// <param name="first">First XML.</param>
/// <param name="second">Second XML.</param>
/// <param name="replace">If set to <see langword="true"/> replaces
/// text values from <paramref name="first"/> with the ones in
/// <paramref name="second"/> if nodes are equal.</param>
/// <returns>The merged XML.</returns>
public static XmlDocument Merge( IXPathNavigable first, IXPathNavigable second, bool replace )
{
// Holds the merged results.
StringBuilder sb = new StringBuilder();
XmlTextWriter tw = new XmlTextWriter(new StringWriter(sb));
tw.Formatting = Formatting.None;
// Specify whether second node replaces text from first one.
XsltArgumentList args = new XsltArgumentList();
args.AddParam("replace", String.Empty, replace);
Transformation.Transform(Input, args, tw, new XmlNodeResolver(first, second));
tw.Flush();
XmlDocument doc = new XmlDocument();
doc.LoadXml(sb.ToString());
return doc;
}
}
Note that I embedded the stylesheet in the assembly, and loaded everything only once in the static ctor. Oliver' stylesheet receives the names of the two files to process and loads them with the XSLT document function. I have "fooled" the XslTransform by providing dummy urls for both files (mem://first and mem://second and through a custom XmlResolver answer the stylesheet request for those files. That's what the XmlNodeResolver I created is about (not rocket science, I must admit :o)):
/// <summary>
/// Resolves the dummy URL locations to the parameters received.
/// </summary>
private class XmlNodeResolver : XmlResolver
{
IXPathNavigable _first;
IXPathNavigable _second;
public XmlNodeResolver(IXPathNavigable first, IXPathNavigable second)
{
_first = first;
_second = second;
}
public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
{
if ( absoluteUri.Authority == First )
return _first.CreateNavigator();
else if ( absoluteUri.Authority == Second )
return _second.CreateNavigator();
return null;
}
public override System.Net.ICredentials Credentials
{
set {}
}
}
This is a private class nested in the XmlMerger class.
Given the following NUnit test for it:
[Test]
public void MergeNodes()
{
XmlDocument first = new XmlDocument();
XmlDocument second = new XmlDocument();
first.LoadXml(@"
<themes>
<theme id='appl'>
<title xml:lang='nl'>Toepassingen</title>
</theme>
</themes>");
second.LoadXml(@"
<themes>
<theme id='doc' />
<theme id='appl'>
<title xml:lang='en'>Applications</title>
</theme>
</themes>");
XmlNode result = XmlMerge.Merge(first, second, true);
System.Diagnostics.Debug.Write(result.OuterXml);
}
The merged results are:
<themes>
<theme id="doc" />
<theme id="appl">
<title xml:lang="nl">Toepassingen</title>
<title xml:lang="en">Applications</title>
</theme>
</themes>
+ The 'real' NUnit test without pretty indenting and a proper assert for passing:
[Test]
public void MergeNodes()
{
XmlDocument first = new XmlDocument();
XmlDocument second = new XmlDocument();
first.LoadXml(@"<themes><theme id='appl'><title xml:lang='nl'>Toepassingen</title></theme></themes>");
second.LoadXml(@"<themes><theme id='doc' /><theme id='appl'><title xml:lang='en'>Applications</title></theme></themes>");
XmlNode result = XmlMerge.Merge(first, second, true);
Assertion.AssertEquals("Merged documents are not equal",
"<themes><theme id='doc' /><theme id='appl'><title xml:lang='nl'>Toepassingen</title><title xml:lang='en'>Applications</title></theme></themes>",
result.OuterXml);
}
-
Office Documents XML
-
Note: this entry has moved.
Regarding all the latest excitement around MS 'release' of its suite XML format XSDs, I can't help but wonder why didn't they contribute with OASIS to built a truly open document format all suites could use as their default representation.
Given the latest "openness" MS is showing, it seems it can't avoid comming out with propietary competing formats instead of helping the standard organizations, just like they did with InfoPath instead of supporting XForms, and will be doing with WVG (windows vector graphics) instead of supporting SVG, using propietary styling in XAML instead of CSS, rolling a new build system called MSBuid instead of integrating NAnt, and list goes on... sadly. And if any of those standards fall short in some functionality or their argued "customer requirements", they why don't they just contribute to the working groups to improve them?
On the other hand, they seem pretty happy and enthusiastic about supporting XPath, XSLT, XQuery and many others... contributed C#/CLI to ECMA... why don't they make this enthusiasm for standards a corporate-wide attitude? One thing is for sure: if they did, there would be much less complaints about its products (i.e. blaim the W3C/OASIS/ECMA/whoever) and many more (remorseless) MS-lovers.
-
Where on earth did my IComponents go? (VS.NET Whidbey Web Apps)
-
Note: this entry has moved.
Non-visual components (those staying in a zone at the bottom of a webform -and also WinForms-) are SO cool: they have rich design-time features (designers, editors, full-blown editing UIs) that are UI-independent (can be used on windows and web forms, think of Dataset, SqlConnection, EventLog, etc.), can provide extensility to preexistent controls through IExtenderProvider, can interact with VS.NET services, generate code for the code-behind InitializeComponent, hook custom serializers, etc., etc.
Being SO cool, and having developed a couple products (even a yet-another-MVC) that heavily rely on them, it was more than surprising (to say the least) to find that they no longer appear at design-time in Whidbey Web Developer!! Everything seems to work (still) at run-time, but no design-time support!! So all the code serialization, designers and editors are completely useless now :S.
I honestly hope this is only a matter of early bits and time constraint, and that they are not obsoletting a feature introduced just a couple years ago (and a very good and usefull one indeed).
-
XmlValidatingReader for arbitrary XmlReaders: I had a dream...
-
Note: this entry has moved.
Every now and then, I face this really bothering bug, which is that even when the XmlValidatingReader accepts an XmlReader in its constructor, it will actually throw a run-time exception if it receives anything other than an XmlTextReader
The constructor is the one to blame, as Reflector shows up-front:
public XmlValidatingReader(XmlReader reader)
{
this._PartialContentNodeType = 0;
base..ctor();
this._CoreReader = (reader as XmlTextReader);
if (this._CoreReader == null)
{
throw new ArgumentException("reader");
}
And the exception isn't too helpful either, right? Damn.... now I'm trying to layer rules validation in the middle of the XmlReader and the XmlValidatingReader and I'm starting to think I'm out of luck... :S
Oleg mentioned this some time ago too. :(
-
XAML Assembly/Namespace mapping
-
Note: this entry has moved.
DonXML comments on a really ugly feature of XAML: processing instructions for namespace/assembly mapping?!?!?!?
Well, I'm proposing another (more xml-friendly?) approach:
<my:FancyControl xmlns:my="MyAssemblyName#MyNamespaceForFancyControl">
This way, the namespace is sort of a fragment identifier inside the assembly, which makes more sense, doesn't it?
-
Automatic VS.NET Command Prompt
-
Note: this entry has moved.
Tired of going to the "Visual Studio .NET 2003 Command Prompt" program files shortcut and then having to move to the desired folder? Want to get the environment variables set whenever you run "cmd"?
Create a .reg file with the following code and merge it in your registry:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor]
"AutoRun"="\"C:\\Program Files\\Microsoft Visual Studio .NET 2003\\Common7\\Tools\\vsvars32.bat\""
Needless to say, it must point to your installation path.