コード例 #1
0
        /// <summary>
        /// Casts the value of the inner Expression to a Boolean
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override IValuedNode Evaluate(SparqlEvaluationContext context, int bindingID)
        {
            IValuedNode n = this._expr.Evaluate(context, bindingID);//.CoerceToBoolean();

            //if (n == null)
            //{
            //    throw new RdfQueryException("Cannot cast a Null to a xsd:boolean");
            //}

            ////New method should be much faster
            //if (n is BooleanNode) return n;
            //return new BooleanNode(null, n.AsBoolean());

            switch (n.NodeType)
            {
            case NodeType.Blank:
            case NodeType.GraphLiteral:
            case NodeType.Uri:
                throw new RdfQueryException("Cannot cast a Blank/URI/Graph Literal Node to a xsd:boolean");

            case NodeType.Literal:
                //See if the value can be cast
                if (n is BooleanNode)
                {
                    return(n);
                }
                ILiteralNode lit = (ILiteralNode)n;
                if (lit.DataType != null)
                {
                    string dt = lit.DataType.ToString();

                    if (dt.Equals(XmlSpecsHelper.XmlSchemaDataTypeBoolean))
                    {
                        //Already a Boolean
                        bool b;
                        if (Boolean.TryParse(lit.Value, out b))
                        {
                            return(new BooleanNode(lit.Graph, b));
                        }
                        else
                        {
                            throw new RdfQueryException("Invalid Lexical Form for xsd:boolean");
                        }
                    }

                    //Cast based on Numeric Type
                    SparqlNumericType type = SparqlSpecsHelper.GetNumericTypeFromDataTypeUri(dt);

                    switch (type)
                    {
                    case SparqlNumericType.Decimal:
                        Decimal dec;
                        if (Decimal.TryParse(lit.Value, out dec))
                        {
                            if (dec.Equals(Decimal.Zero))
                            {
                                return(new BooleanNode(lit.Graph, false));
                            }
                            else
                            {
                                return(new BooleanNode(lit.Graph, true));
                            }
                        }
                        else
                        {
                            throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:decimal as an intermediate stage in casting to a xsd:boolean");
                        }

                    case SparqlNumericType.Double:
                        Double dbl;
                        if (Double.TryParse(lit.Value, out dbl))
                        {
                            if (Double.IsNaN(dbl) || dbl == 0.0d)
                            {
                                return(new BooleanNode(lit.Graph, false));
                            }
                            else
                            {
                                return(new BooleanNode(lit.Graph, true));
                            }
                        }
                        else
                        {
                            throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:double as an intermediate stage in casting to a xsd:boolean");
                        }

                    case SparqlNumericType.Integer:
                        Int64 i;
                        if (Int64.TryParse(lit.Value, out i))
                        {
                            if (i == 0)
                            {
                                return(new BooleanNode(lit.Graph, false));
                            }
                            else
                            {
                                return(new BooleanNode(lit.Graph, true));
                            }
                        }
                        else
                        {
                            throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:integer as an intermediate stage in casting to a xsd:boolean");
                        }

                    case SparqlNumericType.NaN:
                        if (dt.Equals(XmlSpecsHelper.XmlSchemaDataTypeDateTime))
                        {
                            //DateTime cast forbidden
                            throw new RdfQueryException("Cannot cast a xsd:dateTime to a xsd:boolean");
                        }
                        else
                        {
                            Boolean b;
                            if (Boolean.TryParse(lit.Value, out b))
                            {
                                return(new BooleanNode(lit.Graph, b));
                            }
                            else
                            {
                                throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:boolean");
                            }
                        }

                    default:
                        throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:boolean");
                    }
                }
                else
                {
                    Boolean b;
                    if (Boolean.TryParse(lit.Value, out b))
                    {
                        return(new BooleanNode(lit.Graph, b));
                    }
                    else
                    {
                        throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:boolean");
                    }
                }

            default:
                throw new RdfQueryException("Cannot cast an Unknown Node to a xsd:decimal");
            }
        }
コード例 #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(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));
            }
        }
コード例 #3
0
        /// <summary>
        /// Casts the value of the inner Expression to a Boolean
        /// </summary>
        /// <param name="context">Evaluation Context</param>
        /// <param name="bindingID">Binding ID</param>
        /// <returns></returns>
        public override INode Value(SparqlEvaluationContext context, int bindingID)
        {
            INode n = this._expr.Value(context, bindingID);

            if (n == null)
            {
                throw new RdfQueryException("Cannot cast a Null to a xsd:boolean");
            }

            switch (n.NodeType)
            {
            case NodeType.Blank:
            case NodeType.GraphLiteral:
            case NodeType.Uri:
                throw new RdfQueryException("Cannot cast a Blank/URI/Graph Literal Node to a xsd:boolean");

            case NodeType.Literal:
                //See if the value can be cast
                ILiteralNode lit = (ILiteralNode)n;
                if (lit.DataType != null)
                {
                    String dt = lit.DataType.ToString();

                    if (dt.Equals(XmlSpecsHelper.XmlSchemaDataTypeBoolean))
                    {
                        //Already a Boolean
                        return(lit);
                    }

                    //Cast based on Numeric Type
                    SparqlNumericType type = SparqlSpecsHelper.GetNumericTypeFromDataTypeUri(dt);

                    switch (type)
                    {
                    case SparqlNumericType.Decimal:
                        Decimal dec;
                        if (Decimal.TryParse(lit.Value, out dec))
                        {
                            if (dec.Equals(Decimal.Zero))
                            {
                                return(new LiteralNode(lit.Graph, "false", new Uri(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                            }
                            else
                            {
                                return(new LiteralNode(lit.Graph, "true", new Uri(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                            }
                        }
                        else
                        {
                            throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:decimal as an intermediate stage in casting to a xsd:boolean");
                        }

                    case SparqlNumericType.Double:
                        Double dbl;
                        if (Double.TryParse(lit.Value, out dbl))
                        {
                            if (Double.IsNaN(dbl) || dbl == 0.0d)
                            {
                                return(new LiteralNode(lit.Graph, "false", new Uri(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                            }
                            else
                            {
                                return(new LiteralNode(lit.Graph, "true", new Uri(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                            }
                        }
                        else
                        {
                            throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:double as an intermediate stage in casting to a xsd:boolean");
                        }

                    case SparqlNumericType.Integer:
                        Int64 i;
                        if (Int64.TryParse(lit.Value, out i))
                        {
                            if (i == 0)
                            {
                                return(new LiteralNode(lit.Graph, "false", new Uri(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                            }
                            else
                            {
                                return(new LiteralNode(lit.Graph, "true", new Uri(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                            }
                        }
                        else
                        {
                            throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:integer as an intermediate stage in casting to a xsd:boolean");
                        }

                    case SparqlNumericType.NaN:
                        if (dt.Equals(XmlSpecsHelper.XmlSchemaDataTypeDateTime))
                        {
                            //DateTime cast forbidden
                            throw new RdfQueryException("Cannot cast a xsd:dateTime to a xsd:boolean");
                        }
                        else
                        {
                            Boolean b;
                            if (Boolean.TryParse(lit.Value, out b))
                            {
                                return(new LiteralNode(lit.Graph, b.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                            }
                            else
                            {
                                throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:boolean");
                            }
                        }

                    default:
                        throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:boolean");
                    }
                }
                else
                {
                    Boolean b;
                    if (Boolean.TryParse(lit.Value, out b))
                    {
                        return(new LiteralNode(lit.Graph, b.ToString(), new Uri(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                    }
                    else
                    {
                        throw new RdfQueryException("Cannot cast the value '" + lit.Value + "' to a xsd:boolean");
                    }
                }

            default:
                throw new RdfQueryException("Cannot cast an Unknown Node to a xsd:decimal");
            }
        }