Лучший способ проверить наличие XPath в файле XML? - PullRequest
6 голосов
/ 29 октября 2008

В последнее время я использую XPathDocument и XNavigator для анализа XML-файла на предмет заданного XPath и атрибута. Это работает очень хорошо, когда я заранее знаю, что такое XPath.

Иногда, хотя XPath будет одним из нескольких возможных значений XPath, я хотел бы иметь возможность проверить, существует ли данный XPath.

В случае, если я неправильно понимаю номенклатуру, вот что я называю XPath - учитывая этот BLOB-объект:

<foo>
    <bar baz="This is the value of the attribute named baz">
</foo>

Возможно, я ищу то, что я называю XPath «// foo / bar», а затем читаю атрибут «baz», чтобы получить значение.

Пример кода, который я использую для этого:

XPathDocument document = new XPathDocument(filename);
XPathNavigator navigator = document.CreateNavigator();
XPathNavigator node = navigator.SelectSingleNode("//foo/bar");
if(node.HasAttributes)
{
    Console.WriteLine(node.GetAttribute("baz", string.Empty));
}

Теперь, если произойдет сбой вызова navigator.SelectSingleNode, он вернет исключение NullReferenceException или XPathException. Я могу поймать оба из них и рефакторировать вышеупомянутое в тест, чтобы видеть, возвращает ли данный XPath исключение, но мне было интересно, был ли лучший способ?

Я не видел ничего очевидного в Intellisense. XPathNavigator имеет .HasAttributes и .HasChildren, но если не считать итерации по пути по одному узлу за раз, я не вижу ничего более приятного в использовании.

Ответы [ 7 ]

10 голосов
/ 29 октября 2008

Если вы указали действительный XPath, но он ничего не соответствует, SelectSingleNode не будет выбросить a NullReferenceException - он просто вернет ноль.

Если вы передадите SelectSingleNode некоторый синтаксически недопустимый XPath, тогда он выдаст XPathException.

Так что обычно вам просто нужно проверить, было ли возвращенное значение нулевым или нет.

1 голос
/ 21 октября 2016

Я думаю, что нехорошо создавать объект XMLNode, выполняя navigator.SelectSingleNode (...).

Вы должны использовать навигатор. Вместо этого ():

if (Convert.ToBoolean(navigator.Evaluate(@"boolean(//foo/bar)"))) {...}
1 голос
/ 29 октября 2008
 var baz = navigator.SelectSingleNode("//foo/bar/@baz");
 if (baz != null) Console.WriteLine(baz);
0 голосов
/ 29 октября 2008

Я бы, наверное, конкретизировал свой xpath.

        var doc = XDocument.Load(fileName);

        var results = from r in doc.XPathSelectElements("/foo/bar[count(@baz) > 0]")
                      select r.Attribute("baz");

        foreach (String s in results)
            Console.WriteLine(s);
0 голосов
/ 29 октября 2008
var node = XDocument.Load(filename)
                    .Descendants("bar")
                    .SingleOrDefault(e=>e.Attribute("baz") != null);

if (node != null) Console.WriteLine(node.Attribute("baz").Value);
0 голосов
/ 29 октября 2008

Если node == null, то node.HasAttributes выдаст NullReferenceException. Такая ситуация возникает, когда //foo/bar не соответствует ни одному элементу в документе XML.

0 голосов
/ 29 октября 2008

Из памяти может содержать ошибки.

XDocument doc = XDocument.Load("foo.xml");

var att = from a in doc.Descendants("bar")
          select a.Attribute("baz")

foreach (var item in att) {
    if (item != null) { ... }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...