#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()
будет включать как элемент, так и текстовые узлы
Комментарии:
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 для просмотра дерева.