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
- ActionFrame.cs
- XhtmlBasicFormAdapter.cs
- XmlImplementation.cs
- PerfCounters.cs
- SingleObjectCollection.cs
- TextBreakpoint.cs
- LocalFileSettingsProvider.cs
- PaginationProgressEventArgs.cs
- CompilerWrapper.cs
- DynamicRenderer.cs
- ReversePositionQuery.cs
- IntAverageAggregationOperator.cs
- PrintDocument.cs
- PrintEvent.cs
- ButtonColumn.cs
- GridViewSelectEventArgs.cs
- ConfigViewGenerator.cs
- TraceContext.cs
- XmlHierarchicalDataSourceView.cs
- DifferencingCollection.cs
- WizardSideBarListControlItem.cs
- SafeMILHandle.cs
- BulletChrome.cs
- WindowsFormsHost.cs
- CodeDirectionExpression.cs
- RsaKeyIdentifierClause.cs
- bidPrivateBase.cs
- RefExpr.cs
- StylusEventArgs.cs
- ClickablePoint.cs
- _PooledStream.cs
- UnknownWrapper.cs
- JsonWriter.cs
- ConstraintStruct.cs
- QueryCacheEntry.cs
- WebServicesInteroperability.cs
- BoundColumn.cs
- SmiTypedGetterSetter.cs
- TextServicesContext.cs
- XmlDocumentType.cs
- PersonalizationStateQuery.cs
- RowTypeElement.cs
- MappedMetaModel.cs
- NonSerializedAttribute.cs
- ObjectQueryProvider.cs
- HtmlShimManager.cs
- sqlstateclientmanager.cs
- DetailsViewPageEventArgs.cs
- ISAPIApplicationHost.cs
- Transform3D.cs
- AdapterUtil.cs
- CompilerGeneratedAttribute.cs
- PrintDialog.cs
- HtmlAnchor.cs
- ControlBuilder.cs
- ScriptIgnoreAttribute.cs
- ListItemCollection.cs
- FactoryGenerator.cs
- EditingCoordinator.cs
- SiteMapDataSource.cs
- ToggleProviderWrapper.cs
- PageClientProxyGenerator.cs
- CollectionViewGroup.cs
- ColumnResizeUndoUnit.cs
- ImageMetadata.cs
- BufferedReadStream.cs
- HandleCollector.cs
- WeakHashtable.cs
- AssemblyHelper.cs
- _TLSstream.cs
- X509Certificate2Collection.cs
- TemplateBaseAction.cs
- AppearanceEditorPart.cs
- PropertyDescriptorGridEntry.cs
- LineVisual.cs
- UnhandledExceptionEventArgs.cs
- TextEndOfSegment.cs
- SqlDelegatedTransaction.cs
- FtpWebRequest.cs
- MenuItemBinding.cs
- TableCellAutomationPeer.cs
- URLString.cs
- ClockController.cs
- HwndSourceKeyboardInputSite.cs
- AccessDataSourceView.cs
- IISMapPath.cs
- ControlSerializer.cs
- WebControlAdapter.cs
- AuthStoreRoleProvider.cs
- DesignerVerbCollection.cs
- RC2CryptoServiceProvider.cs
- PropertyChangingEventArgs.cs
- SqlBooleanizer.cs
- DBDataPermission.cs
- BuilderPropertyEntry.cs
- FixedSOMTableRow.cs
- DtrList.cs
- ErrorFormatterPage.cs
- CustomDictionarySources.cs
- RangeBase.cs