-
-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
XPathNodeIterator.Count returns one less that the actual count w/ XPath2SelectNodes #59
Comments
@Todo18 |
Sure. Here's a sample test: using System.Diagnostics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Xml.XPath;
using Wmhelp.XPath2;
namespace Test.Functional
{
[TestClass]
public class Compliancy
{
[TestMethod]
public void XPath2SelectNodes_Count_Returns_Number_Of_Items_In_Expression()
{
var xIn = Resources.Provider.LoadXmlDocument("count_xml.xml");
var navigator = xIn.CreateNavigator();
var brandSet = navigator.XPath2SelectNodes("/report/brand");
var brandCount = (int)navigator.XPath2Evaluate("count(/report/brand)");
var highVolumeBrandSet = navigator.XPath2SelectNodes("/report/brand[units > 20000]");
var highVolumeBrandCount = (int)navigator.XPath2Evaluate("count(/report/brand[units > 20000])");
Debug.Assert(brandCount == 5); // These are just here to assert the correct (expected) value
Assert.AreEqual(brandCount, brandSet.Count);
Debug.Assert(highVolumeBrandCount == 2); // These are just here to assert the correct (expected) value
Assert.AreEqual(highVolumeBrandCount, highVolumeBrandSet.Count);
}
}
} We tested this with the following input file (count_xml.xml): <?xml version="1.0" encoding="utf-8"?>
<!-- chocolate.xml -->
<report month="8" year="2006">
<title>Chocolate bar sales</title>
<brand>
<name>Lindt</name>
<units>27408</units>
</brand>
<brand>
<name>Callebaut</name>
<units>8203</units>
</brand>
<brand>
<name>Valrhona</name>
<units>22101</units>
</brand>
<brand>
<name>Perugina</name>
<units>14336</units>
</brand>
<brand>
<name>Ghirardelli</name>
<units>19268</units>
</brand>
</report> When we run the test, if returns 1 less (4 resp. 1) than the expected number of items in the node set of each expression (5 resp. 2), and one less than the |
@Todo18
And these run fine? Can you double check what's the difference? |
@Todo18 |
Apologies, I'm short on time these days. I will inspect our integration and let you know my findings. |
@Todo18 Did you have time to check? |
I'm checking it today. :) |
I've taken the exact same code that you provided above, together with the v1.1.3 Nuget from the built-in Nuget manager in VS, and it fails the test. I have no idea what's going on. I'll look into it a bit more later today. |
So I've had some more time to check. Before diving further into (proprietary) code, could you please try and rephrase your unit tests to conform to ours, and check the (new) results, because there seems to be a discrepancy between |
Please note that my unit tests are the same as your unit test. Please look at |
To my knowledge, they are not the same: To illustrate my point, I've added a second assertion to our unit tests, which succeeds, while the original assertion still fails. Assert.AreEqual(brandCount, brandSet.Cast<object>().Count()); // Succeeds
Assert.AreEqual(brandCount, brandSet.Count); // Fails |
According to the documentation: https://learn.microsoft.com/en-us/dotnet/api/system.xml.xpath.xpathnodeiterator.count?view=net-7.0 Count => Gets the index of the last node in the selected set of nodes. |
True, but positions start counting at 1 according to the XPath specs, so this interpretation of Count makes sense when you have for example 3 nodes with indices 1 to 3. (See here, for example: https://learn.microsoft.com/en-us/dotnet/api/system.xml.xpath.xpathnodeiterator.currentposition?view=net-7.0, or: https://www.w3.org/TR/2010/REC-xpath20-20101214/#eval_context) So the indexing needs some tinkering, I guess. Fiddle to illustrate: https://dotnetfiddle.net/QuErKT |
But |
I printed the first item of the set, not the last. It was simply to illustrate the numbering of indices behind the scenes. But you're right, I've adjusted the fiddle to illustrate my point better. ;) |
We've swapped MS's built-in XPath 1.0 processor with the XPath2.Net library and are conducting a couple of (unit) tests, and have noticed something weird about the Count property (of the XPathNodeIterator). Logically, and according to MSDN (and the reference implementation by MS), Count returns the index/position of the last node in the set. Positions start counting at 1 according to the XPath specs, so this interpretation of Count makes sense when you have for example 3 nodes with indices 1 to 3.
However, when swapping libs, Count suddenly returns 2 for a set with 3 nodes, 0 for a set with 1 node, and -1 for the empty set. Could it be that indices start at 0 in the implementation, or are we missing something obvious?
Regardless, thanks for this amazing library!
The text was updated successfully, but these errors were encountered: