Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / XmlUtils / System / Xml / Xsl / XPath / XPathQilFactory.cs / 1305376 / XPathQilFactory.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- using System.Diagnostics; using System.Xml.Schema; using System.Xml.Xsl.Qil; using System.Xml.Xsl.Runtime; namespace System.Xml.Xsl.XPath { using Res = System.Xml.Utils.Res; using T = XmlQueryTypeFactory; internal class XPathQilFactory : QilPatternFactory { public XPathQilFactory(QilFactory f, bool debug) : base(f, debug) { } // Helper methods used in addition to QilPatternFactory's ones public QilNode Error(string res, QilNode args) { return Error(InvokeFormatMessage(String(res), args)); } public QilNode Error(ISourceLineInfo lineInfo, string res, params string[] args) { return Error(String(XslLoadException.CreateMessage(lineInfo, res, args))); } public QilIterator FirstNode(QilNode n) { CheckNodeSet(n); QilIterator i = For(DocOrderDistinct(n)); return For(Filter(i, Eq(PositionOf(i), Int32(1)))); } public bool IsAnyType(QilNode n) { XmlQueryType xt = n.XmlType; bool result = !(xt.IsStrict || xt.IsNode); Debug.Assert(result == (xt.TypeCode == XmlTypeCode.Item || xt.TypeCode == XmlTypeCode.AnyAtomicType), "What else can it be?"); return result; } [Conditional("DEBUG")] public void CheckAny(QilNode n) { Debug.Assert(n != null && IsAnyType(n), "Must be of 'any' type"); } [Conditional("DEBUG")] public void CheckNode(QilNode n) { Debug.Assert(n != null && n.XmlType.IsSingleton && n.XmlType.IsNode, "Must be a singleton node"); } [Conditional("DEBUG")] public void CheckNodeSet(QilNode n) { Debug.Assert(n != null && n.XmlType.IsNode, "Must be a node-set"); } [Conditional("DEBUG")] public void CheckNodeNotRtf(QilNode n) { Debug.Assert(n != null && n.XmlType.IsSingleton && n.XmlType.IsNode && n.XmlType.IsNotRtf, "Must be a singleton node and not an Rtf"); } [Conditional("DEBUG")] public void CheckString(QilNode n) { Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.StringX), "Must be a singleton string"); } [Conditional("DEBUG")] public void CheckStringS(QilNode n) { Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.StringXS), "Must be a sequence of strings"); } [Conditional("DEBUG")] public void CheckDouble(QilNode n) { Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.DoubleX), "Must be a singleton Double"); } [Conditional("DEBUG")] public void CheckBool(QilNode n) { Debug.Assert(n != null && n.XmlType.IsSubtypeOf(T.BooleanX), "Must be a singleton Bool"); } // Return true if inferred type of the given expression is never a subtype of T.NodeS public bool CannotBeNodeSet(QilNode n) { XmlQueryType xt = n.XmlType; // Do not report compile error if n is a VarPar, whose inferred type forbids nodes (SQLBUDT 339398) return xt.IsAtomicValue && !xt.IsEmpty && !(n is QilIterator); } public QilNode SafeDocOrderDistinct(QilNode n) { XmlQueryType xt = n.XmlType; if (xt.MaybeMany) { if (xt.IsNode && xt.IsNotRtf) { // node-set return DocOrderDistinct(n); } else if (!xt.IsAtomicValue) { QilIterator i; return Loop(i = Let(n), Conditional(Gt(Length(i), Int32(1)), DocOrderDistinct(TypeAssert(i, T.NodeNotRtfS)), i ) ); } } return n; } public QilNode InvokeFormatMessage(QilNode res, QilNode args) { CheckString(res); CheckStringS(args); return XsltInvokeEarlyBound(QName("format-message"), XsltMethods.FormatMessage, T.StringX, new QilNode[] { res, args } ); } #region Comparisons public QilNode InvokeEqualityOperator(QilNodeType op, QilNode left, QilNode right) { Debug.Assert(op == QilNodeType.Eq || op == QilNodeType.Ne); double opCode; left = TypeAssert(left, T.ItemS); right = TypeAssert(right, T.ItemS); switch (op) { case QilNodeType.Eq: opCode = (double)XsltLibrary.ComparisonOperator.Eq; break; default: opCode = (double)XsltLibrary.ComparisonOperator.Ne; break; } return XsltInvokeEarlyBound(QName("EqualityOperator"), XsltMethods.EqualityOperator, T.BooleanX, new QilNode[] { Double(opCode), left, right } ); } public QilNode InvokeRelationalOperator(QilNodeType op, QilNode left, QilNode right) { Debug.Assert(op == QilNodeType.Lt || op == QilNodeType.Le || op == QilNodeType.Gt || op == QilNodeType.Ge); double opCode; left = TypeAssert(left, T.ItemS); right = TypeAssert(right, T.ItemS); switch (op) { case QilNodeType.Lt: opCode = (double)XsltLibrary.ComparisonOperator.Lt; break; case QilNodeType.Le: opCode = (double)XsltLibrary.ComparisonOperator.Le; break; case QilNodeType.Gt: opCode = (double)XsltLibrary.ComparisonOperator.Gt; break; default: opCode = (double)XsltLibrary.ComparisonOperator.Ge; break; } return XsltInvokeEarlyBound(QName("RelationalOperator"), XsltMethods.RelationalOperator, T.BooleanX, new QilNode[] { Double(opCode), left, right } ); } #endregion #region Type Conversions [Conditional("DEBUG")] private void ExpectAny(QilNode n) { Debug.Assert(IsAnyType(n), "Unexpected expression type: " + n.XmlType.ToString()); } public QilNode ConvertToType(XmlTypeCode requiredType, QilNode n) { switch (requiredType) { case XmlTypeCode.String : return ConvertToString(n); case XmlTypeCode.Double : return ConvertToNumber(n); case XmlTypeCode.Boolean : return ConvertToBoolean(n); case XmlTypeCode.Node : return EnsureNodeSet(n); case XmlTypeCode.Item : return n; default : Debug.Fail("Unexpected XmlTypeCode: " + requiredType); return null; } } // XPath spec $4.2, string() public QilNode ConvertToString(QilNode n) { switch (n.XmlType.TypeCode) { case XmlTypeCode.Boolean : return ( n.NodeType == QilNodeType.True ? (QilNode) String("true") : n.NodeType == QilNodeType.False ? (QilNode) String("false") : /*default: */ (QilNode) Conditional(n, String("true"), String("false")) ); case XmlTypeCode.Double : return (n.NodeType == QilNodeType.LiteralDouble ? (QilNode) String(XPathConvert.DoubleToString((double)(QilLiteral)n)) : (QilNode) XsltConvert(n, T.StringX) ); case XmlTypeCode.String : return n; default : if (n.XmlType.IsNode) { return XPathNodeValue(SafeDocOrderDistinct(n)); } ExpectAny(n); return XsltConvert(n, T.StringX); } } // XPath spec $4.3, boolean() public QilNode ConvertToBoolean(QilNode n) { switch (n.XmlType.TypeCode) { case XmlTypeCode.Boolean : return n; case XmlTypeCode.Double : // (x < 0 || 0 < x) == (x != 0) && !Double.IsNaN(x) QilIterator i; return (n.NodeType == QilNodeType.LiteralDouble ? Boolean((double)(QilLiteral)n < 0 || 0 < (double)(QilLiteral)n) : Loop(i = Let(n), Or(Lt(i, Double(0)), Lt(Double(0), i))) ); case XmlTypeCode.String : return (n.NodeType == QilNodeType.LiteralString ? Boolean(((string)(QilLiteral)n).Length != 0) : Ne(StrLength(n), Int32(0)) ); default: if (n.XmlType.IsNode) { return Not(IsEmpty(n)); } ExpectAny(n); return XsltConvert(n, T.BooleanX); } } // XPath spec $4.4, number() public QilNode ConvertToNumber(QilNode n) { switch (n.XmlType.TypeCode) { case XmlTypeCode.Boolean : return ( n.NodeType == QilNodeType.True ? (QilNode) Double(1) : n.NodeType == QilNodeType.False ? (QilNode) Double(0) : /*default: */ (QilNode) Conditional(n, Double(1), Double(0)) ); case XmlTypeCode.Double : return n; case XmlTypeCode.String : return XsltConvert(n, T.DoubleX); default: if (n.XmlType.IsNode) { return XsltConvert(XPathNodeValue(SafeDocOrderDistinct(n)), T.DoubleX); } ExpectAny(n); return XsltConvert(n, T.DoubleX); } } public QilNode ConvertToNode(QilNode n) { if (n.XmlType.IsNode && n.XmlType.IsNotRtf && n.XmlType.IsSingleton) { return n; } return XsltConvert(n, T.NodeNotRtf); } public QilNode ConvertToNodeSet(QilNode n) { if (n.XmlType.IsNode && n.XmlType.IsNotRtf) { return n; } return XsltConvert(n, T.NodeNotRtfS); } // Returns null if the given expression is never a node-set public QilNode TryEnsureNodeSet(QilNode n) { if (n.XmlType.IsNode && n.XmlType.IsNotRtf) { return n; } if (CannotBeNodeSet(n)) { return null; } // Ensure it is not an Rtf at runtime return InvokeEnsureNodeSet(n); } // Throws an exception if the given expression is never a node-set public QilNode EnsureNodeSet(QilNode n) { QilNode result = TryEnsureNodeSet(n); if (result == null) { throw new XPathCompileException(Res.XPath_NodeSetExpected); } return result; } public QilNode InvokeEnsureNodeSet(QilNode n) { return XsltInvokeEarlyBound(QName("ensure-node-set"), XsltMethods.EnsureNodeSet, T.NodeSDod, new QilNode[] { n } ); } #endregion #region Other XPath Functions public QilNode Id(QilNode context, QilNode id) { CheckNodeNotRtf(context); if (id.XmlType.IsSingleton) { return Deref(context, ConvertToString(id)); } QilIterator i; return Loop(i = For(id), Deref(context, ConvertToString(i))); } public QilNode InvokeStartsWith(QilNode str1, QilNode str2) { CheckString(str1); CheckString(str2); return XsltInvokeEarlyBound(QName("starts-with"), XsltMethods.StartsWith, T.BooleanX, new QilNode[] { str1, str2 } ); } public QilNode InvokeContains(QilNode str1, QilNode str2) { CheckString(str1); CheckString(str2); return XsltInvokeEarlyBound(QName("contains"), XsltMethods.Contains, T.BooleanX, new QilNode[] { str1, str2 } ); } public QilNode InvokeSubstringBefore(QilNode str1, QilNode str2) { CheckString(str1); CheckString(str2); return XsltInvokeEarlyBound(QName("substring-before"), XsltMethods.SubstringBefore, T.StringX, new QilNode[] { str1, str2 } ); } public QilNode InvokeSubstringAfter(QilNode str1, QilNode str2) { CheckString(str1); CheckString(str2); return XsltInvokeEarlyBound(QName("substring-after"), XsltMethods.SubstringAfter, T.StringX, new QilNode[] { str1, str2 } ); } public QilNode InvokeSubstring(QilNode str, QilNode start) { CheckString(str); CheckDouble(start); return XsltInvokeEarlyBound(QName("substring"), XsltMethods.Substring2, T.StringX, new QilNode[] { str, start } ); } public QilNode InvokeSubstring(QilNode str, QilNode start, QilNode length) { CheckString(str); CheckDouble(start); CheckDouble(length); return XsltInvokeEarlyBound(QName("substring"), XsltMethods.Substring3, T.StringX, new QilNode[] { str, start, length } ); } public QilNode InvokeNormalizeSpace(QilNode str) { CheckString(str); return XsltInvokeEarlyBound(QName("normalize-space"), XsltMethods.NormalizeSpace, T.StringX, new QilNode[] { str } ); } public QilNode InvokeTranslate(QilNode str1, QilNode str2, QilNode str3) { CheckString(str1); CheckString(str2); CheckString(str3); return XsltInvokeEarlyBound(QName("translate"), XsltMethods.Translate, T.StringX, new QilNode[] { str1, str2, str3 } ); } public QilNode InvokeLang(QilNode lang, QilNode context) { CheckString(lang); CheckNodeNotRtf(context); return XsltInvokeEarlyBound(QName("lang"), XsltMethods.Lang, T.BooleanX, new QilNode[] { lang, context } ); } public QilNode InvokeFloor(QilNode value) { CheckDouble(value); return XsltInvokeEarlyBound(QName("floor"), XsltMethods.Floor, T.DoubleX, new QilNode[] { value } ); } public QilNode InvokeCeiling(QilNode value) { CheckDouble(value); return XsltInvokeEarlyBound(QName("ceiling"), XsltMethods.Ceiling, T.DoubleX, new QilNode[] { value } ); } public QilNode InvokeRound(QilNode value) { CheckDouble(value); return XsltInvokeEarlyBound(QName("round"), XsltMethods.Round, T.DoubleX, new QilNode[] { value } ); } #endregion } } // 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
- FixedSOMFixedBlock.cs
- HtmlHistory.cs
- DataFieldConverter.cs
- COM2Enum.cs
- ToolStripSettings.cs
- HttpCookiesSection.cs
- CodeExporter.cs
- CheckBoxRenderer.cs
- HyperLink.cs
- ConfigurationPermission.cs
- HtmlInputSubmit.cs
- Menu.cs
- InputLanguageSource.cs
- PropertyRecord.cs
- QueryCacheKey.cs
- PipelineModuleStepContainer.cs
- DebuggerAttributes.cs
- BorderGapMaskConverter.cs
- FloaterBaseParagraph.cs
- RegexRunnerFactory.cs
- PageHandlerFactory.cs
- ConcurrentQueue.cs
- SQLBinaryStorage.cs
- SecUtil.cs
- RequestTimeoutManager.cs
- Highlights.cs
- PartialArray.cs
- ApplyImportsAction.cs
- Int32CollectionConverter.cs
- ListBox.cs
- PingOptions.cs
- StylusButtonCollection.cs
- WebRequestModulesSection.cs
- SemanticResolver.cs
- ResourcesGenerator.cs
- RepeaterItem.cs
- StaticSiteMapProvider.cs
- ListViewDeletedEventArgs.cs
- WorkflowFileItem.cs
- XmlSerializableReader.cs
- AuthenticationServiceManager.cs
- BamlLocalizer.cs
- CommentAction.cs
- SecurityChannel.cs
- Stroke2.cs
- ContextProperty.cs
- UserControlFileEditor.cs
- Parameter.cs
- GeneralTransform2DTo3D.cs
- SafeRegistryHandle.cs
- GlobalAllocSafeHandle.cs
- DesignerVerb.cs
- SystemIcons.cs
- LineSegment.cs
- TdsParserHelperClasses.cs
- TemplatePartAttribute.cs
- ProtocolException.cs
- UpnEndpointIdentity.cs
- PerformanceCounterLib.cs
- SqlTrackingService.cs
- RotateTransform3D.cs
- TraceHwndHost.cs
- DynamicValidatorEventArgs.cs
- FormatException.cs
- Attributes.cs
- TdsParserStaticMethods.cs
- EntityClientCacheEntry.cs
- ActiveXSerializer.cs
- InvalidDataException.cs
- EdmMember.cs
- MessageQueueConverter.cs
- serverconfig.cs
- LiteralControl.cs
- CombinedGeometry.cs
- SmtpLoginAuthenticationModule.cs
- xsdvalidator.cs
- TreeIterators.cs
- FormViewInsertEventArgs.cs
- OleDbCommand.cs
- IntSecurity.cs
- QueryableFilterRepeater.cs
- ServicePointManagerElement.cs
- ScrollEvent.cs
- Variable.cs
- SerialPinChanges.cs
- Size.cs
- ConstNode.cs
- ToolbarAUtomationPeer.cs
- BindingCollection.cs
- SymmetricSecurityProtocolFactory.cs
- DataGridViewLinkCell.cs
- PeerNameResolver.cs
- BmpBitmapDecoder.cs
- ClientBuildManager.cs
- UseLicense.cs
- UnsafeNativeMethodsPenimc.cs
- RenderData.cs
- StrokeRenderer.cs
- BackStopAuthenticationModule.cs
- ParallelEnumerableWrapper.cs