Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / Xml / System / Xml / XPath / Internal / CompiledXpathExpr.cs / 1 / CompiledXpathExpr.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace MS.Internal.Xml.XPath { using System; using System.Xml; using System.Xml.XPath; using System.Diagnostics; using System.Globalization; using System.Collections; using System.Xml.Xsl; internal class CompiledXpathExpr : XPathExpression { Query query; string expr; bool needContext; internal CompiledXpathExpr(Query query, string expression, bool needContext) { this.query = query; this.expr = expression; this.needContext = needContext; } internal Query QueryTree { get { if (needContext) { throw XPathException.Create(Res.Xp_NoContext); } return query; } } public override string Expression { get { return expr; } } public virtual void CheckErrors() { Debug.Assert(query != null, "In case of error in XPath we create ErrorXPathExpression"); } public override void AddSort(object expr, IComparer comparer) { // sort makes sense only when we are dealing with a query that // returns a nodeset. Query evalExpr; if (expr is string) { evalExpr = new QueryBuilder().Build((string)expr, out needContext); // this will throw if expr is invalid } else if (expr is CompiledXpathExpr) { evalExpr = ((CompiledXpathExpr)expr).QueryTree; } else { throw XPathException.Create(Res.Xp_BadQueryObject); } SortQuery sortQuery = query as SortQuery; if (sortQuery == null) { query = sortQuery = new SortQuery(query); } sortQuery.AddSort(evalExpr, comparer); } public override void AddSort(object expr, XmlSortOrder order, XmlCaseOrder caseOrder, string lang, XmlDataType dataType) { AddSort(expr, new XPathComparerHelper(order, caseOrder, lang, dataType)); } public override XPathExpression Clone() { return new CompiledXpathExpr(Query.Clone(query), expr, needContext); } public override void SetContext(XmlNamespaceManager nsManager) { XsltContext xsltContext = nsManager as XsltContext; if(xsltContext == null) { if(nsManager == null) { nsManager = new XmlNamespaceManager(new NameTable()); } xsltContext = new UndefinedXsltContext(nsManager); } query.SetXsltContext(xsltContext); needContext = false; } public override void SetContext(IXmlNamespaceResolver nsResolver) { XmlNamespaceManager nsManager = nsResolver as XmlNamespaceManager; if (nsManager == null) { if (nsResolver != null) { nsManager = new XmlNamespaceManager(new NameTable()); } } SetContext(nsManager); } public override XPathResultType ReturnType { get { return query.StaticType; } } private class UndefinedXsltContext : XsltContext { private XmlNamespaceManager nsManager; public UndefinedXsltContext(XmlNamespaceManager nsManager) : base(/*dummy*/false) { this.nsManager = nsManager; } //----- Namespace support ----- public override string DefaultNamespace { get { return string.Empty; } } public override string LookupNamespace(string prefix) { Debug.Assert(prefix != null); if(prefix.Length == 0) { return string.Empty; } string ns = this.nsManager.LookupNamespace(prefix); if(ns == null) { throw XPathException.Create(Res.XmlUndefinedAlias, prefix); } Debug.Assert(ns.Length != 0, "No XPath prefix can be mapped to 'null namespace'"); return ns; } //----- XsltContext support ----- public override IXsltContextVariable ResolveVariable(string prefix, string name) { throw XPathException.Create(Res.Xp_UndefinedXsltContext); } public override IXsltContextFunction ResolveFunction(string prefix, string name, XPathResultType[] ArgTypes) { throw XPathException.Create(Res.Xp_UndefinedXsltContext); } public override bool Whitespace { get{ return false; } } public override bool PreserveWhitespace(XPathNavigator node) { return false; } public override int CompareDocument (string baseUri, string nextbaseUri) { return string.CompareOrdinal(baseUri, nextbaseUri); } } } internal sealed class XPathComparerHelper : IComparer { private XmlSortOrder order; private XmlCaseOrder caseOrder; private CultureInfo cinfo; private XmlDataType dataType; public XPathComparerHelper(XmlSortOrder order, XmlCaseOrder caseOrder, string lang, XmlDataType dataType) { if (lang == null) { this.cinfo = System.Threading.Thread.CurrentThread.CurrentCulture; } else { try { this.cinfo = new CultureInfo(lang); } catch (System.ArgumentException) { throw; // Throwing an XsltException would be a breaking change } } if (order == XmlSortOrder.Descending) { if (caseOrder == XmlCaseOrder.LowerFirst) { caseOrder = XmlCaseOrder.UpperFirst; } else if (caseOrder == XmlCaseOrder.UpperFirst) { caseOrder = XmlCaseOrder.LowerFirst; } } this.order = order; this.caseOrder = caseOrder; this.dataType = dataType; } public Int32 Compare(object x, object y) { Int32 sortOrder = (this.order == XmlSortOrder.Ascending) ? 1 : -1; switch(this.dataType) { case XmlDataType.Text: string s1 = Convert.ToString(x, this.cinfo); string s2 = Convert.ToString(y, this.cinfo); Int32 result = string.Compare(s1, s2, (this.caseOrder == XmlCaseOrder.None) ? false : true, this.cinfo); if (result != 0 || this.caseOrder == XmlCaseOrder.None) return (sortOrder * result); // If we came this far, it means that strings s1 and s2 are // equal to each other when case is ignored. Now it's time to check // and see if they differ in case only and take into account the user // requested case order for sorting purposes. Int32 caseOrder = (this.caseOrder == XmlCaseOrder.LowerFirst) ? 1 : -1; result = string.Compare(s1, s2, false, this.cinfo); return (caseOrder * result); case XmlDataType.Number: double r1 = XmlConvert.ToXPathDouble(x); double r2 = XmlConvert.ToXPathDouble(y); // trying to return the result of (r1 - r2) casted down // to an Int32 can be dangerous. E.g 100.01 - 100.00 would result // erroneously in zero when casted down to Int32. if (r1 > r2) { return (1*sortOrder); } else if (r1 < r2) { return (-1*sortOrder); } else { if (r1 == r2) { return 0; } if (Double.IsNaN(r1)) { if (Double.IsNaN(r2)) { return 0; } //r2 is not NaN .NaN comes before any other number return (-1*sortOrder); } //r2 is NaN. So it should come after r1 return (1*sortOrder); } default: // dataType doesn't support any other value throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) ); } // switch } // Compare () } // class XPathComparerHelper } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace MS.Internal.Xml.XPath { using System; using System.Xml; using System.Xml.XPath; using System.Diagnostics; using System.Globalization; using System.Collections; using System.Xml.Xsl; internal class CompiledXpathExpr : XPathExpression { Query query; string expr; bool needContext; internal CompiledXpathExpr(Query query, string expression, bool needContext) { this.query = query; this.expr = expression; this.needContext = needContext; } internal Query QueryTree { get { if (needContext) { throw XPathException.Create(Res.Xp_NoContext); } return query; } } public override string Expression { get { return expr; } } public virtual void CheckErrors() { Debug.Assert(query != null, "In case of error in XPath we create ErrorXPathExpression"); } public override void AddSort(object expr, IComparer comparer) { // sort makes sense only when we are dealing with a query that // returns a nodeset. Query evalExpr; if (expr is string) { evalExpr = new QueryBuilder().Build((string)expr, out needContext); // this will throw if expr is invalid } else if (expr is CompiledXpathExpr) { evalExpr = ((CompiledXpathExpr)expr).QueryTree; } else { throw XPathException.Create(Res.Xp_BadQueryObject); } SortQuery sortQuery = query as SortQuery; if (sortQuery == null) { query = sortQuery = new SortQuery(query); } sortQuery.AddSort(evalExpr, comparer); } public override void AddSort(object expr, XmlSortOrder order, XmlCaseOrder caseOrder, string lang, XmlDataType dataType) { AddSort(expr, new XPathComparerHelper(order, caseOrder, lang, dataType)); } public override XPathExpression Clone() { return new CompiledXpathExpr(Query.Clone(query), expr, needContext); } public override void SetContext(XmlNamespaceManager nsManager) { XsltContext xsltContext = nsManager as XsltContext; if(xsltContext == null) { if(nsManager == null) { nsManager = new XmlNamespaceManager(new NameTable()); } xsltContext = new UndefinedXsltContext(nsManager); } query.SetXsltContext(xsltContext); needContext = false; } public override void SetContext(IXmlNamespaceResolver nsResolver) { XmlNamespaceManager nsManager = nsResolver as XmlNamespaceManager; if (nsManager == null) { if (nsResolver != null) { nsManager = new XmlNamespaceManager(new NameTable()); } } SetContext(nsManager); } public override XPathResultType ReturnType { get { return query.StaticType; } } private class UndefinedXsltContext : XsltContext { private XmlNamespaceManager nsManager; public UndefinedXsltContext(XmlNamespaceManager nsManager) : base(/*dummy*/false) { this.nsManager = nsManager; } //----- Namespace support ----- public override string DefaultNamespace { get { return string.Empty; } } public override string LookupNamespace(string prefix) { Debug.Assert(prefix != null); if(prefix.Length == 0) { return string.Empty; } string ns = this.nsManager.LookupNamespace(prefix); if(ns == null) { throw XPathException.Create(Res.XmlUndefinedAlias, prefix); } Debug.Assert(ns.Length != 0, "No XPath prefix can be mapped to 'null namespace'"); return ns; } //----- XsltContext support ----- public override IXsltContextVariable ResolveVariable(string prefix, string name) { throw XPathException.Create(Res.Xp_UndefinedXsltContext); } public override IXsltContextFunction ResolveFunction(string prefix, string name, XPathResultType[] ArgTypes) { throw XPathException.Create(Res.Xp_UndefinedXsltContext); } public override bool Whitespace { get{ return false; } } public override bool PreserveWhitespace(XPathNavigator node) { return false; } public override int CompareDocument (string baseUri, string nextbaseUri) { return string.CompareOrdinal(baseUri, nextbaseUri); } } } internal sealed class XPathComparerHelper : IComparer { private XmlSortOrder order; private XmlCaseOrder caseOrder; private CultureInfo cinfo; private XmlDataType dataType; public XPathComparerHelper(XmlSortOrder order, XmlCaseOrder caseOrder, string lang, XmlDataType dataType) { if (lang == null) { this.cinfo = System.Threading.Thread.CurrentThread.CurrentCulture; } else { try { this.cinfo = new CultureInfo(lang); } catch (System.ArgumentException) { throw; // Throwing an XsltException would be a breaking change } } if (order == XmlSortOrder.Descending) { if (caseOrder == XmlCaseOrder.LowerFirst) { caseOrder = XmlCaseOrder.UpperFirst; } else if (caseOrder == XmlCaseOrder.UpperFirst) { caseOrder = XmlCaseOrder.LowerFirst; } } this.order = order; this.caseOrder = caseOrder; this.dataType = dataType; } public Int32 Compare(object x, object y) { Int32 sortOrder = (this.order == XmlSortOrder.Ascending) ? 1 : -1; switch(this.dataType) { case XmlDataType.Text: string s1 = Convert.ToString(x, this.cinfo); string s2 = Convert.ToString(y, this.cinfo); Int32 result = string.Compare(s1, s2, (this.caseOrder == XmlCaseOrder.None) ? false : true, this.cinfo); if (result != 0 || this.caseOrder == XmlCaseOrder.None) return (sortOrder * result); // If we came this far, it means that strings s1 and s2 are // equal to each other when case is ignored. Now it's time to check // and see if they differ in case only and take into account the user // requested case order for sorting purposes. Int32 caseOrder = (this.caseOrder == XmlCaseOrder.LowerFirst) ? 1 : -1; result = string.Compare(s1, s2, false, this.cinfo); return (caseOrder * result); case XmlDataType.Number: double r1 = XmlConvert.ToXPathDouble(x); double r2 = XmlConvert.ToXPathDouble(y); // trying to return the result of (r1 - r2) casted down // to an Int32 can be dangerous. E.g 100.01 - 100.00 would result // erroneously in zero when casted down to Int32. if (r1 > r2) { return (1*sortOrder); } else if (r1 < r2) { return (-1*sortOrder); } else { if (r1 == r2) { return 0; } if (Double.IsNaN(r1)) { if (Double.IsNaN(r2)) { return 0; } //r2 is not NaN .NaN comes before any other number return (-1*sortOrder); } //r2 is NaN. So it should come after r1 return (1*sortOrder); } default: // dataType doesn't support any other value throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) ); } // switch } // Compare () } // class XPathComparerHelper } // 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
- BinaryReader.cs
- HttpResponseHeader.cs
- HighContrastHelper.cs
- TargetControlTypeCache.cs
- Propagator.Evaluator.cs
- WinEventHandler.cs
- CompilationUtil.cs
- MobileSysDescriptionAttribute.cs
- TreeNodeMouseHoverEvent.cs
- RegexTypeEditor.cs
- storepermissionattribute.cs
- sqlinternaltransaction.cs
- ListViewGroupItemCollection.cs
- Cursors.cs
- BezierSegment.cs
- FixedStringLookup.cs
- Int32Animation.cs
- URLMembershipCondition.cs
- ConstrainedGroup.cs
- PeerCollaborationPermission.cs
- initElementDictionary.cs
- ColumnMapCopier.cs
- PathTooLongException.cs
- Expression.cs
- RewritingSimplifier.cs
- TrackingMemoryStream.cs
- PerformanceCounterCategory.cs
- BitArray.cs
- RTLAwareMessageBox.cs
- WorkBatch.cs
- DetailsViewRowCollection.cs
- WebPartConnection.cs
- StreamUpgradeInitiator.cs
- PartialClassGenerationTask.cs
- X509IssuerSerialKeyIdentifierClause.cs
- Transform3DCollection.cs
- DataServiceKeyAttribute.cs
- CompiledIdentityConstraint.cs
- ConfigurationFileMap.cs
- NameValuePair.cs
- Size3DConverter.cs
- RequiredFieldValidator.cs
- ComponentResourceKeyConverter.cs
- SystemIPv6InterfaceProperties.cs
- SqlEnums.cs
- EmptyQuery.cs
- SchemaTableOptionalColumn.cs
- ObjectManager.cs
- HostingEnvironmentException.cs
- OperationBehaviorAttribute.cs
- MarkupProperty.cs
- Point3DValueSerializer.cs
- FontFamilyIdentifier.cs
- DynamicDataResources.Designer.cs
- QuaternionAnimationBase.cs
- SqlParameterCollection.cs
- PerformanceCounterCategory.cs
- UriSection.cs
- _UriTypeConverter.cs
- BuildDependencySet.cs
- BrowserInteropHelper.cs
- QilInvokeLateBound.cs
- OdbcCommand.cs
- ThreadInterruptedException.cs
- IriParsingElement.cs
- XMLSchema.cs
- PKCS1MaskGenerationMethod.cs
- State.cs
- MediaCommands.cs
- FormViewPageEventArgs.cs
- LeaseManager.cs
- StrokeCollectionDefaultValueFactory.cs
- MimeBasePart.cs
- DispatcherHooks.cs
- ButtonFlatAdapter.cs
- PageEventArgs.cs
- _SSPISessionCache.cs
- ImageKeyConverter.cs
- XmlSchemaComplexContentRestriction.cs
- OLEDB_Enum.cs
- SoapDocumentMethodAttribute.cs
- ByteStreamGeometryContext.cs
- NamedPermissionSet.cs
- CornerRadius.cs
- CodeAttachEventStatement.cs
- ProcessModelInfo.cs
- KnownTypes.cs
- util.cs
- WhileDesigner.cs
- Set.cs
- Queue.cs
- StructuredTypeEmitter.cs
- ItemList.cs
- SerialPinChanges.cs
- ActivityUtilities.cs
- VisualStateChangedEventArgs.cs
- SafeNativeMethodsOther.cs
- MetadataCacheItem.cs
- SchemaMerger.cs
- SrgsRule.cs