|
Relation
--------
The Relation object is a representation of a simple mathematical relation (r). When pulled up from a database, it has fields and records, but for the purpose of bulding an SQL statement, it's only the fields of this relation that matter.
i) A relation may join with another relation. This results in a joined-relation, which is also a relation. This join may be
a) OUTER,
b) INNER or
c) CARTESIAN
ii) A relation may join with another instance of itself, which is still treated as any other join
iii)
Field
-----
i) A literal
ii) A table-column
iii) A expression of any of the 2 above
Query
-----
i) A Query object represents an SQL-select statement
ii) A Query has at least one relation and at least one field
iii) A query can optionally have a Grouping object
iv) Only if a query has a Grouping object, can it optionally have a Having object.
Join
----
i) A Join object represents a connecting condition between 2 relations
ii) A join-condition
|
|
|
|
|
I was dragging this one for some time. We wanted to try embedding all our xml-schema and xsl files in the assembly itself.
Now, I had worked with embedded resources before and at first it seemed a simple 2 step thing: mark the file as "embedded resource" and load it from Assembly.GetManifestResourceStream() . This works for simple cases.
The real problem arises when the xslt-files or schemas refer to other files. For example the directive: <xsl:import href="commonTemplates.xsl"/> in a transformation file refers to an external file and when loading the transformation, the engine (one like System.Xml.XmlTransformation) looks for http://commonTemplates.xsl in the current location and loads its definition along with the current transformation-file.
The problem with an embedded xslt-file is, there's no standard way of referring one embedded-xslt into another. So, as in our example, if the embedded xslt-resource had a <xsl:import href="commonTemplates.xsl"/> in it, the engine would still try to look for http://commonTemplates.xsl in the working folder (\bin etc). And, if we need to keep the referred file in the local path, we beat the whole purpose of embeddig the resource in the first place!
The solution comes in the shape of a helpful class provided by the framework - called XmlResolver[^]
This is a pretty useful class that you can inject into the standard xsl-transformation process of XslTransformation class. The design pattern of XMLResolver is such that when passed into the XMLTransformation::Transform[^] call, it is called to resolve references (like URLs) present in the XSL-transformation source. A derived class of XMLResolver called XMLURLResolver[^] is designed specifically for this. Now, what I wanted is to define a new uri-scheme (like http://, ftp:// etc) and be able to use that in my transformations to refer to 'embedded' files - I picked "ref://". To implement the handling of this new schema, we need to extend the XMLURLResolver class:
public class XmlResourceResolver : XmlUrlResolver
{
...
}
The second step is to override the GetEntity method:
public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
{
Stream stream = null;
switch (absoluteUri.Scheme)
{
case "res":
Assembly assembly = null;
string assemblyfilename = absoluteUri.Host;
if (string.Compare(Assembly.GetExecutingAssembly().GetName().Name, assemblyfilename, true) == 0)
{
assembly = Assembly.GetExecutingAssembly();
}
else if (string.Compare(Assembly.GetEntryAssembly().GetName().Name, assemblyfilename, true) == 0)
{
assembly = Assembly.GetEntryAssembly();
}
else
{
}
string resourceName = assemblyfilename + "." + absoluteUri.Query.Substring(absoluteUri.Query.IndexOf('?') + 1);
resourceName = ResolveResourceName(assembly.GetManifestResourceNames(), resourceName);
stream = assembly.GetManifestResourceStream(resourceName);
return stream;
default:
stream = (Stream)base.GetEntity(absoluteUri, role, ofObjectToReturn);
return stream;
}
}
See that last else in the code above? Its left blank because I don't allow for external assemblies being referred to in my project - its either the GetExecutingAssembly() or GetEntryAssembly() that I use.
The ResolveResourceName method makes sure the original names of the resource is kept intact:
private string ResolveResourceName(string[] names, string resourceName)
{
foreach (string name in names)
{
if (String.Compare(name, resourceName, true) == 0)
return name;
}
return null;
}
-- modified at 13:07 Tuesday 31st January, 2006
|
|
|
|