StefH / XPath2.Net

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

Number expressions need explicit number conversions #32

Closed matthiasmalsy closed 4 years ago

matthiasmalsy commented 4 years ago

Number comparison only works, if an explicit number()-conversion is done.

In the following example, the elements are number types. And I am sure, it worked for me in a former version. (Maybe an old version of XPATH2 or the XPATH-1version of dotnet).

           var xml = new XElement("root",
                new XElement("num1", 8),
                new XElement("num2", 20)
            );

            var nav = xml.CreateNavigator();

            // ok
            Assert.True((bool) nav.XPath2Evaluate("boolean(number(num1) < number(num2))"));
            // fail
            Assert.True((bool) nav.XPath2Evaluate("boolean(num1 < num2)"));

Microsoft XPATH

            var data = new XElement("OTC",
                new XElement("num1", 8),  // same result for "8"
                new XElement("num2", 20)  // same result for "20"
                );

            var xdoc = new XDocument();
            xdoc.Add(data);
            var nav = xdoc.CreateNavigator();
            nav.MoveToFirstChild();

            // true
            var result = (bool)nav.Evaluate("boolean(num1 < num2)");
matthiasmalsy commented 4 years ago

It seems that the behavior is correct. In an untyped schema, the default comparison method is alphabetical (XPATH2.0)

Some other parsers convert the operand to decimal if the other operand is a constant number/expression e.g. "//myvalue20 > 8" ===> number(//myvalue20) > integer(8) I can not find any hint in the XPATH 2.0 specification how to correctly treat this case.

But as already mentioned. This parser always uses alphabetical order. And it seems to be defined in the spec. "//myvalue20 > //myvalue8" ===> string(20) > string(8) ====> false "//myvalue20 > 8" ===> string(20) > integer(8) ====> type mismatch