StefH / XPath2.Net

Lightweight XPath2 for .NET
Microsoft Public License
36 stars 14 forks source link

Calling string() in step fails with Wmhelp.XPath2.XPath2Exception: The function 'string'/0 was not found #23

Closed martin-honnen closed 5 years ago

martin-honnen commented 5 years ago

https://www.w3.org/TR/2007/REC-xpath-functions-20070123/#func-string for XPath 2.0 defines a zero argument version of the string function but trying to use it with XPath2 in the last step of a path (e.g. /root/item/string()) fails with

Unhandled Exception: Wmhelp.XPath2.XPath2Exception: The function 'string'/0 was not found in namespace 'http://www.w3.org/2003/11/xpath-functions' at Wmhelp.XPath2.AST.FuncNode..ctor(XPath2Context context, String name, String ns) at Wmhelp.XPath2.YYParser.yyparse(yyInput yyLex) at Wmhelp.XPath2.YYParser.yyparseSafe(Tokenizer tok, Object yyDebug) at Wmhelp.XPath2.XPath2Expression.Compile(String xpath, IXmlNamespaceResolver resolver) at Wmhelp.XPath2.XmlNodeExtensions.XPath2Evaluate(XmlNode node, String xpath)

Adding

            Add(XmlReservedNs.NsXQueryFunc, "string", 0, XPath2ResultType.String, (context, provider, args) =>
    CoreFuncs.StringValue(context, provider));

in FunctionTable.cs inside of the private FunctionTable() constructor code seems to fix that problem and doesn't seem to cause any of the XQTS test cases to fail that work with XPath2 without that change.

I also tried two test cases that don't work with the current XPath2 but work after above fix:

        [Fact]
        public void XPath2_Call_string_Function_On_Context_Node()
        {
            var doc3 = new XmlDocument() { InnerXml = "<root>foo</root>" };

            var result = doc3.XPath2Evaluate("root/string()") as XPath2NodeIterator;
            result.MoveNext();

            var value = result.Current.ToString();
            Assert.Equal("foo", value);
        }

        [Fact]
        public void XPath2_Call_string_join_On_string_sequence()
        {
            var doc3 = new XmlDocument() { InnerXml = "<root><item>a</item><item>b</item><item>c</item></root>" };

            var result = doc3.XPath2Evaluate("string-join(root/item/string(), ',')") as string;

            Assert.Equal("a,b,c", result);
        }
StefH commented 5 years ago

Good point; I'll update the code.

StefH commented 5 years ago

New NuGet will be ready in some time...

gvdm90 commented 5 years ago

I can confirm that with the latest update of the XPath2 lib (1.0.8) the string() syntax works as expected

StefH commented 5 years ago

Good to hear. Thanks for finding this issue.