Пример #1
0
        /// <summary>
        /// Compares two Nodes
        /// </summary>
        /// <param name="x">Node</param>
        /// <param name="y">Node</param>
        /// <returns></returns>
        public override int Compare(IValuedNode x, IValuedNode y)
        {
            // Nulls are less than everything
            if (x == null && y == null)
            {
                return(0);
            }
            if (x == null)
            {
                return(-1);
            }
            if (y == null)
            {
                return(1);
            }

            // If the Node Types are different use Node ordering
            if (x.NodeType != y.NodeType)
            {
                return(x.CompareTo(y));
            }

            if (x.NodeType == NodeType.Literal)
            {
                try
                {
                    // Do they have supported Data Types?
                    String xtype, ytype;
                    try
                    {
                        xtype = XmlSpecsHelper.GetSupportedDataType(x);
                        ytype = XmlSpecsHelper.GetSupportedDataType(y);
                    }
                    catch (RdfException)
                    {
                        // Can't determine a Data Type for one/both of the Nodes so use Node ordering
                        return(x.CompareTo(y));
                    }

                    if (xtype.Equals(String.Empty) || ytype.Equals(String.Empty))
                    {
                        // One/both has an unknown type
                        if (x.Equals(y))
                        {
                            // If RDF Term equality returns true then we return that they are equal
                            return(0);
                        }
                        else
                        {
                            // If RDF Term equality returns false then we fall back to Node Ordering
                            return(x.CompareTo(y));
                        }
                    }
                    else
                    {
                        // Both have known types
                        SparqlNumericType xnumtype = x.NumericType;
                        SparqlNumericType ynumtype = y.NumericType;
                        SparqlNumericType numtype  = (SparqlNumericType)Math.Max((int)xnumtype, (int)ynumtype);
                        if (numtype != SparqlNumericType.NaN)
                        {
                            if (xnumtype == SparqlNumericType.NaN)
                            {
                                return(1);
                            }
                            else if (ynumtype == SparqlNumericType.NaN)
                            {
                                return(-1);
                            }

                            // Both are Numeric so use Numeric ordering
                            try
                            {
                                return(this.NumericCompare(x, y, numtype));
                            }
                            catch (FormatException)
                            {
                                if (x.Equals(y))
                                {
                                    return(0);
                                }
                                // Otherwise fall back to Node Ordering
                                return(x.CompareTo(y));
                            }
                            catch (RdfQueryException)
                            {
                                // If this errors try RDF Term equality since that might still give equality
                                if (x.Equals(y))
                                {
                                    return(0);
                                }
                                // Otherwise fall back to Node Ordering
                                return(x.CompareTo(y));
                            }
                        }
                        else if (xtype.Equals(ytype))
                        {
                            switch (xtype)
                            {
                            case XmlSpecsHelper.XmlSchemaDataTypeDate:
                                return(DateCompare(x, y));

                            case XmlSpecsHelper.XmlSchemaDataTypeDateTime:
                                return(DateTimeCompare(x, y));

                            case XmlSpecsHelper.XmlSchemaDataTypeString:
                                // Both Strings so use Lexical string ordering
                                return(((ILiteralNode)x).Value.CompareTo(((ILiteralNode)y).Value));

                            default:
                                // Use node ordering
                                return(x.CompareTo(y));
                            }
                        }
                        else
                        {
                            String commontype = XmlSpecsHelper.GetCompatibleSupportedDataType(xtype, ytype, true);
                            if (commontype.Equals(String.Empty))
                            {
                                // Use Node ordering
                                return(x.CompareTo(y));
                            }
                            else
                            {
                                switch (commontype)
                                {
                                case XmlSpecsHelper.XmlSchemaDataTypeDate:
                                    return(DateCompare(x, y));

                                case XmlSpecsHelper.XmlSchemaDataTypeDateTime:
                                    return(DateTimeCompare(x, y));

                                default:
                                    // Use Node ordering
                                    return(x.CompareTo(y));
                                }
                            }
                        }
                    }
                }
                catch
                {
                    // If error then can't determine ordering so fall back to node ordering
                    return(x.CompareTo(y));
                }
            }
            else
            {
                // If not Literals use Node ordering
                return(x.CompareTo(y));
            }
        }
Пример #2
0
        /// <summary>
        /// Compares two Nodes
        /// </summary>
        /// <param name="x">Node</param>
        /// <param name="y">Node</param>
        /// <returns></returns>
        public virtual int Compare(INode x, INode y)
        {
            // Nulls are less than everything
            if (x == null && y == null)
            {
                return(0);
            }
            if (x == null)
            {
                return(-1);
            }
            if (y == null)
            {
                return(1);
            }

            // If the Node Types are different use Node ordering
            if (x.NodeType != y.NodeType)
            {
                return(x.CompareTo(y));
            }

            if (x.NodeType == NodeType.Literal)
            {
                // Do they have supported Data Types?
                String xtype, ytype;
                try
                {
                    xtype = XmlSpecsHelper.GetSupportedDataType(x);
                    ytype = XmlSpecsHelper.GetSupportedDataType(y);
                }
                catch (RdfException)
                {
                    // Can't determine a Data Type for one/both of the Nodes so use Node ordering
                    return(x.CompareTo(y));
                }

                if (xtype.Equals(String.Empty) || ytype.Equals(String.Empty))
                {
                    // One/both has an unknown type
                    if (x.Equals(y))
                    {
                        // If RDF Term equality returns true then we return that they are equal
                        return(0);
                    }
                    else
                    {
                        // If RDF Term equality returns false then we error
                        // UNLESS they have the same Datatype
                        throw new RdfQueryException("Unable to determine ordering since one/both arguments has an Unknown Type");
                    }
                }
                else
                {
                    // Both have known types
                    SparqlNumericType xnumtype = SparqlSpecsHelper.GetNumericTypeFromDataTypeUri(xtype);
                    SparqlNumericType ynumtype = SparqlSpecsHelper.GetNumericTypeFromDataTypeUri(ytype);
                    SparqlNumericType numtype  = (SparqlNumericType)Math.Max((int)xnumtype, (int)ynumtype);
                    if (numtype != SparqlNumericType.NaN)
                    {
                        if (xnumtype == SparqlNumericType.NaN || ynumtype == SparqlNumericType.NaN)
                        {
                            // If one is non-numeric then we can't assume non-equality
                            throw new RdfQueryException("Unable to determine ordering since one/both arguments does not return a Number");
                        }

                        // Both are Numeric so use Numeric ordering
                        try
                        {
                            return(this.NumericCompare(x, y, numtype));
                        }
                        catch (FormatException)
                        {
                            if (x.Equals(y))
                            {
                                return(0);
                            }
                            throw new RdfQueryException("Unable to determine ordering since one/both arguments does not contain a valid value for it's type");
                        }
                        catch (RdfQueryException)
                        {
                            // If this errors try RDF Term equality since
                            if (x.Equals(y))
                            {
                                return(0);
                            }
                            throw new RdfQueryException("Unable to determine ordering since one/both arguments was not a valid numeric");
                        }
                    }
                    else if (xtype.Equals(ytype))
                    {
                        switch (xtype)
                        {
                        case XmlSpecsHelper.XmlSchemaDataTypeDate:
                            return(DateCompare(x, y));

                        case XmlSpecsHelper.XmlSchemaDataTypeDateTime:
                            return(DateTimeCompare(x, y));

                        case XmlSpecsHelper.XmlSchemaDataTypeString:
                            // Both Strings so use Lexical string ordering
#if NETCORE
                            return(Options.DefaultCulture.CompareInfo.Compare(((ILiteralNode)x).Value,
                                                                              ((ILiteralNode)y).Value, Options.DefaultComparisonOptions));
#else
                            return(String.Compare(((ILiteralNode)x).Value, ((ILiteralNode)y).Value, Options.DefaultCulture, Options.DefaultComparisonOptions));
#endif
                        default:
                            // Use node ordering
                            return(x.CompareTo(y));
                        }
                    }
                    else
                    {
                        String commontype = XmlSpecsHelper.GetCompatibleSupportedDataType(xtype, ytype, true);
                        if (commontype.Equals(String.Empty))
                        {
                            // Use Node ordering
                            return(x.CompareTo(y));
                        }
                        else
                        {
                            switch (commontype)
                            {
                            case XmlSpecsHelper.XmlSchemaDataTypeDate:
                                return(DateCompare(x, y));

                            case XmlSpecsHelper.XmlSchemaDataTypeDateTime:
                                return(DateTimeCompare(x, y));

                            default:
                                // Use Node ordering
                                return(x.CompareTo(y));
                            }
                        }
                    }
                }
            }
            else
            {
                // If not Literals use Node ordering
                return(x.CompareTo(y));
            }
        }