Выбирать дочерние узлы, но игнорировать неэлементы с помощью XPath?

#c# #wpf #xml #xpath

#c# #wpf #xml #xpath

Вопрос:

Например, учитывая следующий XML-документ:

 <?xml version="1.0"?>
<UrdaObject>
  <Date>
    <Year>2011</Year>
    <Month>5</Month>
    <Day>18</Day>
    <Hours>8</Hours>
    <Minutes>47</Minutes>
    <Seconds>36</Seconds>
  </Date>
  <random_value>24</random_value>
</UrdaObject>
  

И понимание того, child::node() - Selects all child nodes of the current node как бы я создал XPath (начиная с корневого каталога), который выбирал бы все дочерние узлы, КРОМЕ текста, комментариев и других вещей, которые НЕ являются элементами. Например, при использовании этого кода для создания древовидного представления в WPF:

 // x is some XmlDocument, xmlTree is my WPF TreeView
XmlDataProvider provider = new XmlDataProvider();
provider.Document = x;
Binding binding = new Binding();
binding.Source = provider;
binding.XPath = "child::node()";
xmlTree.SetBinding(TreeView.ItemsSourceProperty, binding);
  

Как бы мне создать свой оператор XPath, чтобы я построил treeview с узлами, идущими полностью вниз и останавливающимися перед необработанным текстом? Например, это сгенерировало бы представление:

 UrdaObject
  Date
    Year
...
  

Вместо…

 UrdaObject
  Date
    Year
      2011 (Don't want this!)
...
  

Примеры XML-файлов предназначены только для меня, чтобы объяснить мою ситуацию. Выражение должно иметь возможность перемещаться по любому допустимому XML-файлу и извлекать элементы, но не отдельный текст.


Как мы это исправили? Я переключил все ссылки child::node() на child::* . Однако я НЕ исправил одну строку в моем XAML, которая вытягивала child::node() . Исправление этой строки привело к корректному поведению приложения… и заставил меня чувствовать себя глупо.

Ответ №1:

child::node() находит все дочерние узлы. child::* находит все узлы элемента.

Комментарии:

1. Я пробовал это ранее, но дочерний элемент :: * также отображал отдельные текстовые записи внутри C # TreeView (учитывая фрагмент кода выше), но привязка сохраняет доступ к текстовому представлению, как если бы это был элемент, и я, кажется, могу это объяснить.

2. … Я беру назад свой комментарий выше. Это исправило проблему, вот почему: я правильно построил запрос, но глупая ошибка в одном из моих шаблонов внутри моего XAML все еще пыталась извлечь ВСЕ элементы, используя node() свойство. Исправление этой проблемы привело к корректной работе treeview. Вау, я чувствую себя глупо из-за того, что пропустил это…

Ответ №2:

это так просто, как * .

(однако это приводит к непосредственным дочерним элементам; если вам нужны все элементы-потомки, это было бы descendant::* )

Ответ №3:

child::* исключит текстовые узлы и оставит только узлы элементов

child::text() будет включать только текстовые узлы

child::node() будет включать как элемент, так и текстовые узлы

http://www.w3.org/TR/xpath/#location-paths

Комментарии:

1. Есть ли способ, которым я могу явно исключить текстовые узлы? Я думаю, проблема в том, что TreeView просматривает XML-файл и все еще извлекает отдельные текстовые узлы и добавляет их, даже при использовании child::*

2. Я дурак, объяснение выше. Однако мне пришлось дать ответ lonesomeday, поскольку у него была более ранняя временная метка.

3. Я думаю, вы путаете то, что выбирает XPath, с тем, как это отображается в TreeView.

Ответ №4:

Не уверен, что это то, чего вы хотите, но можно ли это сделать таким образом?

 var doc =XDocument.Parse(@"

<UrdaObject>
  <Date>
    <Year>2011</Year>
    <Month>5</Month>
    <Day>18</Day>
    <Hours>8</Hours>
    <Minutes>47</Minutes>
    <Seconds>36</Seconds>
  </Date>
  <random_value>24</random_value>
</UrdaObject>
");



        var query = from s in doc.Descendants()
                    select s.Name;


        foreach (var name in query)
        {
            Console.WriteLine(name);
        }
  

Комментарии:

1. 1) Я не использую XDocument в этом проекте, 2) Я несколько ограничен использованием XPath для получения нужного мне результата или некоторыми предыдущими манипуляциями с XML для просмотра дерева.