XmlNode.SelectNode Weirdness (не найден один из двух очень похожих узлов) - PullRequest
0 голосов
/ 17 февраля 2012

Я столкнулся с ошибкой в ​​программном обеспечении, которым я управляю, которое используется для создания ведомостей материалов на основе выбора пользователя. Он работает с большим XML-файлом, который содержит все наши номера деталей, а также написанные нами правила, которые используются для выбора этих номеров деталей на основе выбора, который делают инженеры.

Сегодня я понял, что в одной очень специфической части около половины выборов работают, а другая половина - нет. Вот особенности.

Мы строим строку на основе параметров рассматриваемого правила, эти параметры были установлены на основе выбора пользователя. Эта строка передается методу XmlNode.SelectNode:

mItem = mXMLData.SelectNodes(XPath)

Вот два примера строки xpath, один из которых находит узел, а другой - нет:

А)

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

В)

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

Первая строка, A, не будет возвращать никаких узлов, в то время как вторая строка, B, будет возвращать. Вот сегмент нашей базы данных 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-файлы облегчают манипулирование данными, когда нам нужно внести изменения или что-то в этом роде.

Инструмент, который у нас есть, который его компилирует, также шифрует файл, как я упоминал ранее. У нас также есть версия, которая будет компилировать ее без шифрования, как я уже видел ранее.

При просмотре в незашифрованном виде проблемная строка имела один пробел в '17/16'

при просмотре CSV-файла в блокноте был один пробел.

когда файл CSV просматривался в Excel, он показывал его с двумя пробелами, чтобы столбцы совпали (форматирование Excel, тьфу).

Когда я, наконец, прошел по коду и посмотрел на фактические данные xml в памяти, по которой он искал, в «17.07» было два пробела, поэтому, конечно, он никогда не совпадал.

В конце мне пришлось изменить столбец CSV-файла в Excel, в котором данные диаметра содержались в текстовом формате из числового формата, сохранить его и перекомпилировать. Если бы я снова открыл файл CSV, ничего не изменил и сохранил его, он снова вернул бы туда второй пробел.

Я все исправил, и программа работает.

Спасибо всем за ваши ответы (особенно об инструменте xpathvisualizer, очень удобно). Это было упражнение в разочаровании, которое сожгло весь мой день.

1 Ответ

0 голосов
/ 17 февраля 2012

Я подтвердил, что минимальный пример:

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. Я исключил <Root> из моего образца документа, так как не понимаю, как это может быть актуально.

edit # 1:

Аналогично для VB, не то, чтобы это имело значение, и это не так. Я также заметил, что я использовал SelectSingleNode, а не SelectNodes в моем первом примере. Я исправил это, и это также сработало, как и ожидалось.

...