XQueryCommand.Execute returns empty iterator, issue with external function

Sep 7, 2010 at 1:11 AM
I have the following xquery:
xquery version "1.0";
declare namespace http = "http://expath.org/ns/http-client";
<textarea>{ count(http:send-request((), 'http://qm.codeplex.com/Project/ProjectRss.aspx')) }</textarea>

When I run it returns an empty iterator, I don't even get the textarea element. If I remove the external function call then it runs fine. When I debug the external function is not even called.
This is the external function method:
[XQuerySignature("send-request", NamespaceUri="http://expath.org/ns/http-client", Return=XmlTypeCode.Item, Cardinality=XmlTypeCardinality.OneOrMore)]
public static XQueryNodeIterator SendRequest([XQueryParameter(XmlTypeCode.Node, Cardinality=XmlTypeCardinality.ZeroOrOne)] XPathNavigator p0, [XQueryParameter(XmlTypeCode.String, Cardinality=XmlTypeCardinality.ZeroOrOne)] object p1, [XQueryParameter(XmlTypeCode.Item, Cardinality=XmlTypeCardinality.ZeroOrMore)] XQueryNodeIterator p2)
{
    return QueryMachineConvert.ConvertInput(module.SendRequest(p0, QueryMachineConvert.ConvertOutputToString(p1), QueryMachineConvert.ConvertOutput<XPathItem>(p2)));
}

The processor is not giving me any kind of error message, the query compiles fine, runs fine, but returns nothing.

 

Coordinator
Sep 10, 2010 at 5:05 AM

Your function http:send-request() has a two arguments in xquery and three arguments in implementation

Sep 10, 2010 at 5:12 PM

There are 3 overloads as you can see below. Anyways, the function doesn't even get called.

[DebuggerNonUserCode]
public sealed class myxsl_net_expath_httpclient_XPathHttpClient_e01abc7d
{
    // Fields
    private static XPathHttpClient module = new XPathHttpClient();

    // Methods
    [XQuerySignature("send-request", NamespaceUri="http://expath.org/ns/http-client", Return=XmlTypeCode.Item, Cardinality=XmlTypeCardinality.OneOrMore)]
    public static XQueryNodeIterator SendRequest([XQueryParameter(XmlTypeCode.Node, Cardinality=XmlTypeCardinality.ZeroOrOne)] XPathNavigator p0)
    {
        return QueryMachineConvert.ConvertInput(module.SendRequest(p0));
    }

    [XQuerySignature("send-request", NamespaceUri="http://expath.org/ns/http-client", Return=XmlTypeCode.Item, Cardinality=XmlTypeCardinality.OneOrMore)]
    public static XQueryNodeIterator SendRequest([XQueryParameter(XmlTypeCode.Node, Cardinality=XmlTypeCardinality.ZeroOrOne)] XPathNavigator p0, [XQueryParameter(XmlTypeCode.String, Cardinality=XmlTypeCardinality.ZeroOrOne)] object p1)
    {
        return QueryMachineConvert.ConvertInput(module.SendRequest(p0, QueryMachineConvert.ConvertOutputToString(p1)));
    }

    [XQuerySignature("send-request", NamespaceUri="http://expath.org/ns/http-client", Return=XmlTypeCode.Item, Cardinality=XmlTypeCardinality.OneOrMore)]
    public static XQueryNodeIterator SendRequest([XQueryParameter(XmlTypeCode.Node, Cardinality=XmlTypeCardinality.ZeroOrOne)] XPathNavigator p0, [XQueryParameter(XmlTypeCode.String, Cardinality=XmlTypeCardinality.ZeroOrOne)] object p1, [XQueryParameter(XmlTypeCode.Item, Cardinality=XmlTypeCardinality.ZeroOrMore)] XQueryNodeIterator p2)
    {
        return QueryMachineConvert.ConvertInput(module.SendRequest(p0, QueryMachineConvert.ConvertOutputToString(p1), QueryMachineConvert.ConvertOutput<XPathItem>(p2)));
    }
}

Coordinator
Sep 11, 2010 at 5:20 PM

I see. The signature of first parameter is incorrect. Type XPathNavigator is not allows empty sequences. Try use 

public static XQueryNodeIterator SendRequest([XQueryParameter(XmlTypeCode.Node, Cardinality=XmlTypeCardinality.ZeroOrOne)] Object p0)

and check p0 on Undefined.Value or declare p0 as XQueryNodeIterator

 

Sep 11, 2010 at 8:13 PM

Thanks for finding the problem. I think there's a bug on XQuerySequenceType.ValueType

public Type ValueType
{
    get
    {
        if ((this.Cardinality == XmlTypeCardinality.ZeroOrMore) || (this.Cardinality == XmlTypeCardinality.OneOrMore))
        {
            return typeof(XQueryNodeIterator);
        }
        if (this.IsNode)
        {
            return typeof(XPathNavigator);
        }
        if (this.Cardinality == XmlTypeCardinality.One)
        {
            return this.ItemType;
        }
        return typeof(object);
    }
} 

It returns typeof(XPathNavigator) when Cardonality is ZeroOrOne, but it should return typeof(XQueryNodeIterator) or typeof(Object), right?

 

Sep 12, 2010 at 9:25 PM

The problem was fixed by using Object as the type, XQueryNodeIterator did not work.