#c# #xpath
#c# #xpath
Вопрос:
Я пытаюсь написать XPath для работы с некоторыми XML-узлами.
Пример моего XML приведен ниже (для имени элемента и иллюстрации вложенности).
<Forms>
<Form>
<Control/>
<Control>
<Control></Control>
</Control>
<Control>
<Form><!-- This is the nested one, I don't want the Control children from this-->
<Control/>
</Form>
</Control>
</Form>
Есть ли способ изменить приведенную ниже инструкцию XPath — включить все элементы управления (даже вложенные друг в друга — под «Формой», но не из вложенной формы (см. Форма<2>)? Этот текущий XPath возвращает «Элементы управления», которые находятся под вложенными узлами «Формы».
string xpath = @"/Forms/Form[@id='" node.Attributes["id"].Value "']//Control[@type='GroupItem' or @type='Detail' or @type='GroupHeader']";
Я в основном пытаюсь отключить все теги Control и обернуть их тегом «Controls», поэтому я использую этот Xpath в C # для переформатирования — но я не хочу извлекать управление из вложенной формы, я хочу обернуть их в тег Controls отдельно.
Спасибо за любую помощь!
Комментарии:
1. Пожалуйста, предоставьте полный пример XML-документа (как можно меньшего размера) и выражения XPath, сгенерированного вашим кодом, которое фактически вычисляется. Также предоставьте информацию, какие именно элементы были выбраны.
Ответ №1:
В XPath 2.0
//Control except //Form//Form//Control
или в XPath 1.0
//Control[not(ancestor::Form/ancestor::Form)]
Ответ №2:
Как насчет:
/Forms/Form[@id='blah']/descendant::Control[blah]
при этом используется descendant
ось при поиске элемента управления (по умолчанию child
)
Очевидно, замените blah
— они просто для краткости; важная вещь в приведенном выше descendant::
Комментарии:
1. Я что-то пропустил в примере, в других формах есть вложенная «Форма». Я хочу, чтобы все элементы управления находились где-то под формой, но ни один из них не находился под вложенной формой. Итак, если форма имеет вложенную форму, я хочу, чтобы все элементы управления находились в форме, но не элементы управления в ее вложенной форме.
2. @user53885 — с этим дополнительным, возможно, будет проще сделать это в обычном коде… Вы могли бы сделать это в xpath, но это очень нетривиально
Ответ №3:
Это было бы Control
s только с одним Form
предком:
//Control[count(ancestor::Form)=1]
Редактировать: Лучше
//Control[not(ancestor::Form[2])]