Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / XmlUtils / System / Xml / Xsl / Runtime / XmlQueryContext.cs / 5 / XmlQueryContext.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Xml; using System.Xml.XPath; using System.Xml.Schema; using System.Diagnostics; using System.Reflection; using System.ComponentModel; namespace System.Xml.Xsl.Runtime { using Res = System.Xml.Utils.Res; ////// The context of a query consists of all user-provided information which influences the operation of the /// query. The context manages the following information: /// /// 1. Input data sources, including the default data source if one exists /// 2. Extension objects /// 3. External parameters /// [EditorBrowsable(EditorBrowsableState.Never)] public sealed class XmlQueryContext { private XmlQueryRuntime runtime; private XPathNavigator defaultDataSource; private XmlResolver dataSources; private Hashtable dataSourceCache; private XsltArgumentList argList; private XmlExtensionFunctionTable extFuncsLate; private WhitespaceRuleLookup wsRules; private QueryReaderSettings readerSettings; // If we create reader out of stream we will use these settings ////// This constructor is internal so that external users cannot construct it (and therefore we do not have to test it separately). /// internal XmlQueryContext(XmlQueryRuntime runtime, object defaultDataSource, XmlResolver dataSources, XsltArgumentList argList, WhitespaceRuleLookup wsRules) { this.runtime = runtime; this.dataSources = dataSources; this.dataSourceCache = new Hashtable(); this.argList = argList; this.wsRules = wsRules; if (defaultDataSource is XmlReader) { this.readerSettings = new QueryReaderSettings((XmlReader) defaultDataSource); } else { // Consider allowing users to set DefaultReaderSettings in XsltArgumentList // readerSettings = argList.DefaultReaderSettings; this.readerSettings = new QueryReaderSettings(new NameTable()); } if (defaultDataSource is string) { // Load the default document from a Uri this.defaultDataSource = GetDataSource(defaultDataSource as string, null); if (this.defaultDataSource == null) throw new XslTransformException(Res.XmlIl_UnknownDocument, defaultDataSource as string); } else if (defaultDataSource != null) { this.defaultDataSource = ConstructDocument(defaultDataSource, null, null); } } //----------------------------------------------- // Input data sources //----------------------------------------------- ////// Returns the name table that should be used in the query to atomize search names and to load /// new documents. /// public XmlNameTable QueryNameTable { get { return this.readerSettings.NameTable; } } ////// Returns the name table used by the default data source, or null if there is no default data source. /// public XmlNameTable DefaultNameTable { get { return this.defaultDataSource != null ? this.defaultDataSource.NameTable : null; } } ////// Return the document which is queried by default--i.e. no data source is explicitly selected in the query. /// public XPathNavigator DefaultDataSource { get { // Throw exception if there is no default data source to return if (this.defaultDataSource == null) throw new XslTransformException(Res.XmlIl_NoDefaultDocument, string.Empty); return this.defaultDataSource; } } ////// Fetch the data source specified by "uriRelative" and "uriBase" from the XmlResolver that the user provided. /// If the resolver returns a stream or reader, create an instance of XPathDocument. If the resolver returns an /// XPathNavigator, return the navigator. Throw an exception if no data source was found. /// public XPathNavigator GetDataSource(string uriRelative, string uriBase) { object input; Uri uriResolvedBase, uriResolved; XPathNavigator nav = null; try { // If the data source has already been retrieved, then return the data source from the cache. uriResolvedBase = (uriBase != null) ? this.dataSources.ResolveUri(null, uriBase) : null; uriResolved = this.dataSources.ResolveUri(uriResolvedBase, uriRelative); if (uriResolved != null) nav = this.dataSourceCache[uriResolved] as XPathNavigator; if (nav == null) { // Get the entity from the resolver and ensure it is cached as a document input = this.dataSources.GetEntity(uriResolved, null, null); if (input != null) { // Construct a document from the entity and add the document to the cache nav = ConstructDocument(input, uriRelative, uriResolved); this.dataSourceCache.Add(uriResolved, nav); } } } catch (XslTransformException) { // Don't need to wrap XslTransformException throw; } catch (Exception e) { if (!XmlException.IsCatchableException(e)) { throw; } throw new XslTransformException(e, Res.XmlIl_DocumentLoadError, uriRelative); } return nav; } ////// Ensure that "dataSource" is cached as an XPathDocument and return a navigator over the document. /// private XPathNavigator ConstructDocument(object dataSource, string uriRelative, Uri uriResolved) { Debug.Assert(dataSource != null, "GetType() below assumes dataSource is not null"); Stream stream = dataSource as Stream; if (stream != null) { // Create document from stream XmlReader reader = readerSettings.CreateReader(stream, uriResolved != null ? uriResolved.ToString() : null); try { // Create WhitespaceRuleReader if whitespace should be stripped return new XPathDocument(WhitespaceRuleReader.CreateReader(reader, this.wsRules), XmlSpace.Preserve).CreateNavigator(); } finally { // Always close reader that was opened here reader.Close(); } } else if (dataSource is XmlReader) { // Create document from reader // Create WhitespaceRuleReader if whitespace should be stripped return new XPathDocument(WhitespaceRuleReader.CreateReader(dataSource as XmlReader, this.wsRules), XmlSpace.Preserve).CreateNavigator(); } else if (dataSource is IXPathNavigable) { if (this.wsRules != null) throw new XslTransformException(Res.XmlIl_CantStripNav, string.Empty); return (dataSource as IXPathNavigable).CreateNavigator(); } Debug.Assert(uriRelative != null, "Relative URI should not be null"); throw new XslTransformException(Res.XmlIl_CantResolveEntity, uriRelative, dataSource.GetType().ToString()); } //----------------------------------------------- // External parameters //----------------------------------------------- ////// Get a named parameter from the external argument list. Return null if no argument list was provided, or if /// there is no parameter by that name. /// public object GetParameter(string localName, string namespaceUri) { return (this.argList != null) ? this.argList.GetParam(localName, namespaceUri) : null; } //----------------------------------------------- // Extension objects //----------------------------------------------- ////// Return the extension object that is mapped to the specified namespace, or null if no object is mapped. /// public object GetLateBoundObject(string namespaceUri) { return (this.argList != null) ? this.argList.GetExtensionObject(namespaceUri) : null; } ////// Return true if the late bound object identified by "namespaceUri" contains a method that matches "name". /// public bool LateBoundFunctionExists(string name, string namespaceUri) { object instance; if (this.argList == null) return false; instance = this.argList.GetExtensionObject(namespaceUri); if (instance == null) return false; return new XmlExtensionFunction(name, namespaceUri, -1, instance.GetType(), XmlQueryRuntime.LateBoundFlags).CanBind(); } ////// Get a late-bound extension object from the external argument list. Bind to a method on the object and invoke it, /// passing "args" as arguments. /// public IListInvokeXsltLateBoundFunction(string name, string namespaceUri, IList [] args) { object instance; object[] objActualArgs; XmlQueryType xmlTypeFormalArg; Type clrTypeFormalArg; object objRet; // Get external object instance from argument list (throw if either the list or the instance doesn't exist) instance = (this.argList != null) ? this.argList.GetExtensionObject(namespaceUri) : null; if (instance == null) throw new XslTransformException(Res.Xslt_ScriptInvalidPrefix, namespaceUri); // Bind to a method on the instance object if (this.extFuncsLate == null) this.extFuncsLate = new XmlExtensionFunctionTable(); // Bind to the instance, looking for a matching method (throws if no matching method) XmlExtensionFunction extFunc = this.extFuncsLate.Bind(name, namespaceUri, args.Length, instance.GetType(), XmlQueryRuntime.LateBoundFlags); // Create array which will contain the actual arguments objActualArgs = new object[args.Length]; for (int i = 0; i < args.Length; i++) { // 1. Assume that the input value can only have one of the following 5 Xslt types: // xs:double, xs:string, xs:boolean, node* (can be rtf) // 2. Convert each Rtf value to a NodeSet containing one node. Now the value may only have one of the 4 Xslt types. // 3. Convert from one of the 4 Xslt internal types to the Xslt internal type which is closest to the formal // argument's Xml type (inferred from the Clr type of the formal argument). xmlTypeFormalArg = extFunc.GetXmlArgumentType(i); switch (xmlTypeFormalArg.TypeCode) { case XmlTypeCode.Boolean: objActualArgs[i] = XsltConvert.ToBoolean(args[i]); break; case XmlTypeCode.Double: objActualArgs[i] = XsltConvert.ToDouble(args[i]); break; case XmlTypeCode.String: objActualArgs[i] = XsltConvert.ToString(args[i]); break; case XmlTypeCode.Node: if (xmlTypeFormalArg.IsSingleton) objActualArgs[i] = XsltConvert.ToNode(args[i]); else objActualArgs[i] = XsltConvert.ToNodeSet(args[i]); break; case XmlTypeCode.Item: objActualArgs[i] = args[i]; break; default: Debug.Fail("This XmlTypeCode should never be inferred from a Clr type: " + xmlTypeFormalArg.TypeCode); break; } // 4. Change the Clr representation to the Clr type of the formal argument clrTypeFormalArg = extFunc.GetClrArgumentType(i); if (xmlTypeFormalArg.TypeCode == XmlTypeCode.Item || !clrTypeFormalArg.IsAssignableFrom(objActualArgs[i].GetType())) objActualArgs[i] = this.runtime.ChangeTypeXsltArgument(xmlTypeFormalArg, objActualArgs[i], clrTypeFormalArg); } // 1. Invoke the late bound method objRet = extFunc.Invoke(instance, objActualArgs); // 2. Convert to IList if (objRet == null && extFunc.ClrReturnType == XsltConvert.VoidType) return XmlQueryNodeSequence.Empty; return (IList ) this.runtime.ChangeTypeXsltResult(XmlQueryTypeFactory.ItemS, objRet); } //----------------------------------------------- // Event //----------------------------------------------- /// /// Fire the XsltMessageEncounteredEvent, passing the specified text as the message. /// public void OnXsltMessageEncountered(string message) { XsltMessageEncounteredEventHandler onMessage = (this.argList != null) ? argList.xsltMessageEncountered : null; if (onMessage != null) onMessage(this, new XmlILQueryEventArgs(message)); else Console.WriteLine(message); } } ////// Simple implementation of XsltMessageEncounteredEventArgs. /// internal class XmlILQueryEventArgs : XsltMessageEncounteredEventArgs { private string message; public XmlILQueryEventArgs(string message) { this.message = message; } public override string Message { get { return this.message; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Xml; using System.Xml.XPath; using System.Xml.Schema; using System.Diagnostics; using System.Reflection; using System.ComponentModel; namespace System.Xml.Xsl.Runtime { using Res = System.Xml.Utils.Res; ////// The context of a query consists of all user-provided information which influences the operation of the /// query. The context manages the following information: /// /// 1. Input data sources, including the default data source if one exists /// 2. Extension objects /// 3. External parameters /// [EditorBrowsable(EditorBrowsableState.Never)] public sealed class XmlQueryContext { private XmlQueryRuntime runtime; private XPathNavigator defaultDataSource; private XmlResolver dataSources; private Hashtable dataSourceCache; private XsltArgumentList argList; private XmlExtensionFunctionTable extFuncsLate; private WhitespaceRuleLookup wsRules; private QueryReaderSettings readerSettings; // If we create reader out of stream we will use these settings ////// This constructor is internal so that external users cannot construct it (and therefore we do not have to test it separately). /// internal XmlQueryContext(XmlQueryRuntime runtime, object defaultDataSource, XmlResolver dataSources, XsltArgumentList argList, WhitespaceRuleLookup wsRules) { this.runtime = runtime; this.dataSources = dataSources; this.dataSourceCache = new Hashtable(); this.argList = argList; this.wsRules = wsRules; if (defaultDataSource is XmlReader) { this.readerSettings = new QueryReaderSettings((XmlReader) defaultDataSource); } else { // Consider allowing users to set DefaultReaderSettings in XsltArgumentList // readerSettings = argList.DefaultReaderSettings; this.readerSettings = new QueryReaderSettings(new NameTable()); } if (defaultDataSource is string) { // Load the default document from a Uri this.defaultDataSource = GetDataSource(defaultDataSource as string, null); if (this.defaultDataSource == null) throw new XslTransformException(Res.XmlIl_UnknownDocument, defaultDataSource as string); } else if (defaultDataSource != null) { this.defaultDataSource = ConstructDocument(defaultDataSource, null, null); } } //----------------------------------------------- // Input data sources //----------------------------------------------- ////// Returns the name table that should be used in the query to atomize search names and to load /// new documents. /// public XmlNameTable QueryNameTable { get { return this.readerSettings.NameTable; } } ////// Returns the name table used by the default data source, or null if there is no default data source. /// public XmlNameTable DefaultNameTable { get { return this.defaultDataSource != null ? this.defaultDataSource.NameTable : null; } } ////// Return the document which is queried by default--i.e. no data source is explicitly selected in the query. /// public XPathNavigator DefaultDataSource { get { // Throw exception if there is no default data source to return if (this.defaultDataSource == null) throw new XslTransformException(Res.XmlIl_NoDefaultDocument, string.Empty); return this.defaultDataSource; } } ////// Fetch the data source specified by "uriRelative" and "uriBase" from the XmlResolver that the user provided. /// If the resolver returns a stream or reader, create an instance of XPathDocument. If the resolver returns an /// XPathNavigator, return the navigator. Throw an exception if no data source was found. /// public XPathNavigator GetDataSource(string uriRelative, string uriBase) { object input; Uri uriResolvedBase, uriResolved; XPathNavigator nav = null; try { // If the data source has already been retrieved, then return the data source from the cache. uriResolvedBase = (uriBase != null) ? this.dataSources.ResolveUri(null, uriBase) : null; uriResolved = this.dataSources.ResolveUri(uriResolvedBase, uriRelative); if (uriResolved != null) nav = this.dataSourceCache[uriResolved] as XPathNavigator; if (nav == null) { // Get the entity from the resolver and ensure it is cached as a document input = this.dataSources.GetEntity(uriResolved, null, null); if (input != null) { // Construct a document from the entity and add the document to the cache nav = ConstructDocument(input, uriRelative, uriResolved); this.dataSourceCache.Add(uriResolved, nav); } } } catch (XslTransformException) { // Don't need to wrap XslTransformException throw; } catch (Exception e) { if (!XmlException.IsCatchableException(e)) { throw; } throw new XslTransformException(e, Res.XmlIl_DocumentLoadError, uriRelative); } return nav; } ////// Ensure that "dataSource" is cached as an XPathDocument and return a navigator over the document. /// private XPathNavigator ConstructDocument(object dataSource, string uriRelative, Uri uriResolved) { Debug.Assert(dataSource != null, "GetType() below assumes dataSource is not null"); Stream stream = dataSource as Stream; if (stream != null) { // Create document from stream XmlReader reader = readerSettings.CreateReader(stream, uriResolved != null ? uriResolved.ToString() : null); try { // Create WhitespaceRuleReader if whitespace should be stripped return new XPathDocument(WhitespaceRuleReader.CreateReader(reader, this.wsRules), XmlSpace.Preserve).CreateNavigator(); } finally { // Always close reader that was opened here reader.Close(); } } else if (dataSource is XmlReader) { // Create document from reader // Create WhitespaceRuleReader if whitespace should be stripped return new XPathDocument(WhitespaceRuleReader.CreateReader(dataSource as XmlReader, this.wsRules), XmlSpace.Preserve).CreateNavigator(); } else if (dataSource is IXPathNavigable) { if (this.wsRules != null) throw new XslTransformException(Res.XmlIl_CantStripNav, string.Empty); return (dataSource as IXPathNavigable).CreateNavigator(); } Debug.Assert(uriRelative != null, "Relative URI should not be null"); throw new XslTransformException(Res.XmlIl_CantResolveEntity, uriRelative, dataSource.GetType().ToString()); } //----------------------------------------------- // External parameters //----------------------------------------------- ////// Get a named parameter from the external argument list. Return null if no argument list was provided, or if /// there is no parameter by that name. /// public object GetParameter(string localName, string namespaceUri) { return (this.argList != null) ? this.argList.GetParam(localName, namespaceUri) : null; } //----------------------------------------------- // Extension objects //----------------------------------------------- ////// Return the extension object that is mapped to the specified namespace, or null if no object is mapped. /// public object GetLateBoundObject(string namespaceUri) { return (this.argList != null) ? this.argList.GetExtensionObject(namespaceUri) : null; } ////// Return true if the late bound object identified by "namespaceUri" contains a method that matches "name". /// public bool LateBoundFunctionExists(string name, string namespaceUri) { object instance; if (this.argList == null) return false; instance = this.argList.GetExtensionObject(namespaceUri); if (instance == null) return false; return new XmlExtensionFunction(name, namespaceUri, -1, instance.GetType(), XmlQueryRuntime.LateBoundFlags).CanBind(); } ////// Get a late-bound extension object from the external argument list. Bind to a method on the object and invoke it, /// passing "args" as arguments. /// public IListInvokeXsltLateBoundFunction(string name, string namespaceUri, IList [] args) { object instance; object[] objActualArgs; XmlQueryType xmlTypeFormalArg; Type clrTypeFormalArg; object objRet; // Get external object instance from argument list (throw if either the list or the instance doesn't exist) instance = (this.argList != null) ? this.argList.GetExtensionObject(namespaceUri) : null; if (instance == null) throw new XslTransformException(Res.Xslt_ScriptInvalidPrefix, namespaceUri); // Bind to a method on the instance object if (this.extFuncsLate == null) this.extFuncsLate = new XmlExtensionFunctionTable(); // Bind to the instance, looking for a matching method (throws if no matching method) XmlExtensionFunction extFunc = this.extFuncsLate.Bind(name, namespaceUri, args.Length, instance.GetType(), XmlQueryRuntime.LateBoundFlags); // Create array which will contain the actual arguments objActualArgs = new object[args.Length]; for (int i = 0; i < args.Length; i++) { // 1. Assume that the input value can only have one of the following 5 Xslt types: // xs:double, xs:string, xs:boolean, node* (can be rtf) // 2. Convert each Rtf value to a NodeSet containing one node. Now the value may only have one of the 4 Xslt types. // 3. Convert from one of the 4 Xslt internal types to the Xslt internal type which is closest to the formal // argument's Xml type (inferred from the Clr type of the formal argument). xmlTypeFormalArg = extFunc.GetXmlArgumentType(i); switch (xmlTypeFormalArg.TypeCode) { case XmlTypeCode.Boolean: objActualArgs[i] = XsltConvert.ToBoolean(args[i]); break; case XmlTypeCode.Double: objActualArgs[i] = XsltConvert.ToDouble(args[i]); break; case XmlTypeCode.String: objActualArgs[i] = XsltConvert.ToString(args[i]); break; case XmlTypeCode.Node: if (xmlTypeFormalArg.IsSingleton) objActualArgs[i] = XsltConvert.ToNode(args[i]); else objActualArgs[i] = XsltConvert.ToNodeSet(args[i]); break; case XmlTypeCode.Item: objActualArgs[i] = args[i]; break; default: Debug.Fail("This XmlTypeCode should never be inferred from a Clr type: " + xmlTypeFormalArg.TypeCode); break; } // 4. Change the Clr representation to the Clr type of the formal argument clrTypeFormalArg = extFunc.GetClrArgumentType(i); if (xmlTypeFormalArg.TypeCode == XmlTypeCode.Item || !clrTypeFormalArg.IsAssignableFrom(objActualArgs[i].GetType())) objActualArgs[i] = this.runtime.ChangeTypeXsltArgument(xmlTypeFormalArg, objActualArgs[i], clrTypeFormalArg); } // 1. Invoke the late bound method objRet = extFunc.Invoke(instance, objActualArgs); // 2. Convert to IList if (objRet == null && extFunc.ClrReturnType == XsltConvert.VoidType) return XmlQueryNodeSequence.Empty; return (IList ) this.runtime.ChangeTypeXsltResult(XmlQueryTypeFactory.ItemS, objRet); } //----------------------------------------------- // Event //----------------------------------------------- /// /// Fire the XsltMessageEncounteredEvent, passing the specified text as the message. /// public void OnXsltMessageEncountered(string message) { XsltMessageEncounteredEventHandler onMessage = (this.argList != null) ? argList.xsltMessageEncountered : null; if (onMessage != null) onMessage(this, new XmlILQueryEventArgs(message)); else Console.WriteLine(message); } } ////// Simple implementation of XsltMessageEncounteredEventArgs. /// internal class XmlILQueryEventArgs : XsltMessageEncounteredEventArgs { private string message; public XmlILQueryEventArgs(string message) { this.message = message; } public override string Message { get { return this.message; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- StrokeCollectionDefaultValueFactory.cs
- pingexception.cs
- SchemaLookupTable.cs
- NullableLongSumAggregationOperator.cs
- CheckBoxFlatAdapter.cs
- CacheMemory.cs
- UrlAuthorizationModule.cs
- x509utils.cs
- KeysConverter.cs
- ApplyHostConfigurationBehavior.cs
- DataGridViewUtilities.cs
- MissingFieldException.cs
- TemplateInstanceAttribute.cs
- UnsafeNativeMethods.cs
- StrongNameIdentityPermission.cs
- SecurityPermission.cs
- ChangeConflicts.cs
- State.cs
- ClientSettingsSection.cs
- StateMachine.cs
- StatusBar.cs
- CommonProperties.cs
- InkCanvas.cs
- CharKeyFrameCollection.cs
- SortQuery.cs
- EnumConverter.cs
- NameValueSectionHandler.cs
- CircleHotSpot.cs
- CursorConverter.cs
- SmiRequestExecutor.cs
- XmlTextWriter.cs
- StandardOleMarshalObject.cs
- _AutoWebProxyScriptHelper.cs
- DataBoundControlHelper.cs
- PixelFormat.cs
- SwitchElementsCollection.cs
- ToolStripLocationCancelEventArgs.cs
- DefaultValueConverter.cs
- WebAdminConfigurationHelper.cs
- BamlRecordWriter.cs
- MouseGestureConverter.cs
- SingleAnimation.cs
- ScriptResourceInfo.cs
- CommandBindingCollection.cs
- MobileContainerDesigner.cs
- RoleServiceManager.cs
- FieldTemplateFactory.cs
- __ComObject.cs
- CustomTypeDescriptor.cs
- WrapPanel.cs
- InputElement.cs
- AnimationTimeline.cs
- FontStyleConverter.cs
- AccessorTable.cs
- EntityDataSourceDataSelection.cs
- CodeTypeReferenceSerializer.cs
- CLSCompliantAttribute.cs
- Completion.cs
- Parser.cs
- EventManager.cs
- TextEffectCollection.cs
- ProcessModelInfo.cs
- Event.cs
- Matrix3DValueSerializer.cs
- TreeView.cs
- EdmSchemaError.cs
- ItemCheckedEvent.cs
- RunWorkerCompletedEventArgs.cs
- VectorAnimationBase.cs
- DataBinding.cs
- ScriptingJsonSerializationSection.cs
- WinCategoryAttribute.cs
- ScriptMethodAttribute.cs
- RMEnrollmentPage3.cs
- DataAdapter.cs
- CodeTryCatchFinallyStatement.cs
- DirectoryGroupQuery.cs
- SerialPinChanges.cs
- ShellProvider.cs
- HeaderedContentControl.cs
- AuthenticodeSignatureInformation.cs
- GridPattern.cs
- SynchronizationValidator.cs
- SHA1CryptoServiceProvider.cs
- SiteMapPathDesigner.cs
- UiaCoreApi.cs
- Delegate.cs
- MenuCommands.cs
- IteratorDescriptor.cs
- XPathAncestorIterator.cs
- CompoundFileIOPermission.cs
- EntitySetBase.cs
- Clock.cs
- GridViewRowCollection.cs
- ImageClickEventArgs.cs
- UTF32Encoding.cs
- UInt16.cs
- Int32CollectionConverter.cs
- ObjectQuery.cs
- TextSelectionHighlightLayer.cs