XPath и выбор одного node

Я использую XPath в .NET для анализа XML-документа в соответствии с:

XmlNodeList lotsOStuff = doc.SelectNodes("//stuff");

foreach (XmlNode stuff in lotsOStuff) {
   XmlNode stuffChild = stuff.SelectSingleNode("//stuffChild");
   // ... etc
}

Проблема в том, что запрос XPath для stuffChild всегда возвращает дочерний элемент первого элемента stuff, а не остальных. Может ли XPath не использоваться для запроса отдельного XMLElement?

Ответ 1

// в начале выражения XPath начинается с корня документа. Попробуйте ".//stuffChild"., является сокращением для self:: node(), который задает контекст для поиска, а//является сокращением для оси потомка.

Итак, у вас есть:

XmlNode stuffChild = stuff.SelectSingleNode(".//stuffChild");

что соответствует:

xmlNode stuffChild = stuff.SelectSingleNode( "self:: node()/descendant:: stuffChild" );

xmlNode stuffChild = stuff.SelectSingleNode("self::node()/descendant-or-self::stuffChild");

В случае, если дочерний элемент node может иметь то же имя, что и родительский, вы должны использовать следующий более подробный синтаксис, чтобы убедиться, что вы не повторно выбираете родителя:

xmlNode stuffChild = stuff.SelectSingleNode("self::node()/descendant::stuffChild");

Также обратите внимание, что если "stuffChild" является прямым потомком "материала", вы можете полностью опустить префиксы и просто выбрать "stuffChild".

XmlNode stuffChild = stuff.SelectSingleNode("stuffChild");

W3Schools учебник содержит полезную информацию в удобном для чтения формате.

Ответ 2

//, который вы используете перед stuffChild, означает, что вы ищете элементы stuffChild, начиная с корня.

Если вы хотите начать с текущего node (decendants текущего node), вы должны использовать .//, как в:

stuff.SelectSingleNode(".//stuffChild");

Ответ 3

Если "stuffChild" является дочерним node "stuff", тогда ваш xpath должен быть только:

XmlNode stuffChild = stuff.SelectSingleNode("stuffChild");

Ответ 4

Выбор одиночного node означает, что вам нужен только первый элемент. Итак, лучшее решение:

XmlNode stuffChild = stuff.SelectSingleNode("descendant::stuffChild[1]");