XmlNode.SelectNode 怪异(未找到两个非常相似的节点之一)

发布于 2025-01-05 23:24:59 字数 1887 浏览 0 评论 0原文

我管理的一个软件遇到了一个错误,该软件用于根据用户选择创建物料清单。它使用一个大型 xml 文件,其中包含我们所有的零件号以及我们编写的规则,这些规则用于根据工程师所做的选择来选择这些零件号。

今天我意识到,在一个非常具体的部分,大约一半的选择有效,而另一半则无效。以下是具体细节。

我们根据相关规则的参数构建一个字符串,这些参数是根据用户选择设置的。该字符串被传递到 XmlNode.SelectNode 方法:

mItem = mXMLData.SelectNodes(XPath)

以下是 xpath 字符串的两个示例,一个查找节点,另一个则不查找:

A)

/Root/Items/Item[@DropDownDescription='Ball Bearing' and @Diameter='1 7/16']

B)

/Root/Items/Item[@DropDownDescription='Ball Bearing' and @Diameter='1 11/16']

第一个字符串 A 将不会返回任何节点,而第二根弦,B,will。这是我们的 xml 数据库中包含这些零件编号的部分:(

<Item Key="FanBearing.1.3" ItemNumber="30400074" DropDownDescription="Ball Bearing" Diameter="1 7/16" />
<Item Key="FanBearing.1.4" ItemNumber="30400075" DropDownDescription="Ball Bearing" Diameter="1 11/16" />

我从这些条目中删除了一些无关紧要的数据,以使它们更短且更易于在此处阅读。在这两种情况下,删除的数据几乎相同,区别仅在于成本/权重等)

如您所见,A 和 B 两个条目都在数据文件中。最奇怪的部分是,我已经能够用我们所有不同的轴承尺寸来复制错误,并且它确实找到的那些在数字的小数部分中有一个两位数分子,而那些没有的找到有一位数的分子。当然,这肯定是巧合,因为它只是一根绳子,根本不重要,但它对于我们拥有的每种尺寸都适用。

这就是我所拥有的一切,我一直在与我们的另一位开发人员(实际上编写了该程序的大部分内容的开发人员)讨论过这个问题,但我们都不知所措。如果有人有任何想法,请分享。另外,我尽力在这里提供详尽的信息,但如果需要其他信息,我很乐意添加。

谢谢。

编辑:我终于弄清楚了。

好吧,这最终成为一件非常奇怪的事情,最终与 XmlNode.SelectNode 函数无关。

相关 XML 文件是使用我们在此处从 .csv 文件集合创建的自定义工具编译的。当我们需要进行更改或此类性质的操作时,csv 文件使数据更易于操作。

正如我之前提到的,我们拥有的编译它的工具也会加密该文件。我们还有一个版本可以在不加密的情况下编译它,这就是我之前查看它的方式。

在未加密的情况下查看时,有问题的行在“1 7/16”中有一个空格,

而在记事本中查看 CSV 文件时,有一个空格。

当在 Excel 中查看 CSV 文件时,它会显示两个空格,以便列匹配(Excel 格式,呃)。

当我最终单步执行代码并查看内存中正在搜索的实际 xml 数据时,“1 7/16”有两个空格,所以当然它永远不会匹配。

最后,我不得不将Excel中保存直径数据的CSV文件的列从数字格式更改为文本格式,保存并重新编译。如果我再次打开 CSV 文件,不做任何更改,然后保存它,它会再次将第二个空格放回原处。

不过我已经修好了,并且程序正在运行。

感谢大家的回复(特别是关于 xpathvisibleizer 工具,非常方便)。这是一种挫败感的练习,让我一整天都筋疲力尽。

I ran into a bug with a piece of software I manage that is used to create Bills of Materials based on user selections. It works with a large xml file that contains all of our part numbers as well as rules that we have written that are used to select those part numbers based on the selections that the engineers make.

I realized today that on one very specific part, around half of the selections work while the other half don't. Here are the specifics.

We build a string based on the parameters of the rule in question, those parameters having been set based on the user selection. This string is passed to the XmlNode.SelectNode method:

mItem = mXMLData.SelectNodes(XPath)

Here are two examples of the xpath string, one that finds a node and one that doesn't:

A)

/Root/Items/Item[@DropDownDescription='Ball Bearing' and @Diameter='1 7/16']

B)

/Root/Items/Item[@DropDownDescription='Ball Bearing' and @Diameter='1 11/16']

The first string, A, will not return any nodes, while the second string, B, will. Here is the segment of our xml database that contains those part numbers:

<Item Key="FanBearing.1.3" ItemNumber="30400074" DropDownDescription="Ball Bearing" Diameter="1 7/16" />
<Item Key="FanBearing.1.4" ItemNumber="30400075" DropDownDescription="Ball Bearing" Diameter="1 11/16" />

(I removed some insignificant data from those entries, to make them shorter and easier to read here. In both cases the data removed is near identical, with differences only being costs/weights, etc.)

As you can see, both entries, A and B, are in the data file. The weirdest part is that I've been able to replicate the error with all of our different bearing sizes, and the ones that it does find have a double digit numerator in the fractional part of the number, and the ones that it doesn't find have a single digit numerator. Now that of course has to be a coincidence since it is just a string and should not matter at all, but it has held true for every size we have.

That's all I've got, I've been going over this with one of our other developers (the one that actually wrote the bulk of this program) and we are both at a loss. If anyone has any thoughts, please share. Also, I tried to be as thorough as I could be here, but if there is any need for additional information, I would be happy to add it.

Thanks.

EDIT: I have figured it out, finally.

Ok, so this ended up being a very weird thing that in the end wasn't related to the XmlNode.SelectNode function.

The XML file in question is compiled using a custom tool we created here from a collection of .csv files. The csv files make the data easier to manipulate when we need to make changes or things of that nature.

The tool that we have that compiles it also encrypts the file, as I mentioned earlier. We also have a version that will compile it without encryption which is how I was viewing it earlier.

When viewed unencrypted, the problematic line had one space in '1 7/16'

when the CSV file was viewed in notepad, there was one space.

when the CSV file was viewed in excel, it showed it with two spaces so that the columns matched up (excel formatting, ugh).

When I finally stepped through the code, and looked at the actual xml data in memory that it was searching on, the '1 7/16' had two spaces, so of course it never made a match.

In the end, I had to change the column of the CSV file in excel that held the diameter data to text format from number format, save it, and recompile. If I opened the CSV file again, changed nothing, and saved it, it would once again put the second space back in there.

I got it fixed though, and the program is working.

Thank you everyone for your responses (especially about the xpathvisualizer tool, very handy). This has been an exercise in frustration that burnt up my whole day.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

删除会话 2025-01-12 23:24:59

我已经验证了一个最小的示例:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var doc = new XmlDocument();
            doc.Load(@"..\..\XMLFile1.xml");

            var x1 = doc.SelectSingleNode("Items/Item[@DropDownDescription='Ball Bearing' and @Diameter='1 7/16']");
            var x2 = doc.SelectSingleNode("Items/Item[@DropDownDescription='Ball Bearing' and @Diameter='1 11/16']");
        }
    }
}

...在 C# 和 .NET 4.0 中适用于我。我已将 从示例文档中排除,因为我看不出它有何相关性。

编辑 #1:

对于 VB 来说也是如此,并不是说它应该有任何区别,但事实并非如此。我还注意到我在第一个示例中使用了 SelectSingleNode 而不是 SelectNodes。我纠正了这个问题,它也按预期工作。

I have verified that a minimal example:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var doc = new XmlDocument();
            doc.Load(@"..\..\XMLFile1.xml");

            var x1 = doc.SelectSingleNode("Items/Item[@DropDownDescription='Ball Bearing' and @Diameter='1 7/16']");
            var x2 = doc.SelectSingleNode("Items/Item[@DropDownDescription='Ball Bearing' and @Diameter='1 11/16']");
        }
    }
}

...works for me in C# and .NET 4.0. I have excluded <Root> from my sample document since I cannot see how it could be relevant.

edit #1:

Likewise for VB, not that it should make any difference, and it doesn't. I also noticed that I used SelectSingleNode and not SelectNodes in my first example. I corrected this and it also worked as expected.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文