XPath SelectNodes в .NET
<Document>
<A>
<B>
<C></C>
</B>
</A>
<E>
<F>
<C></C>
</F>
<G>
<C></C>
</G>
</E>
</Document>
Если я загружаю вышеуказанный XML в XmlDocument и делаю SelectSingleNode на A, используя запрос XPath//C
XmlNode oNode = oDocument.SelectSingleNode("E");
XmlNodeList oNodeList = oNode.SelectNodes("//C");
почему он возвращает узлы из под B, когда то, что я ожидал бы, приведет к тому, что он вернет только узлы из под E
Имеют смысл?
Изменить: Как я могу сделать это только с этого node?
Ответы
Ответ 1
Просто: ведущий//означает "на любом уровне" в том же документе, что и выбранный node.
Из spec:
- //para выбирает всех потомков абзаца корня документа и, таким образом, выбирает все элементы para в том же документе, что и контекст node
- .//para выбирает потомки пара элемента контекста node
Ответ 2
Задание .//C
приведет к тому, что вы хотите, иначе XPath начнется с корня документа, а не с текущего node.
Путаница находится в определении //
из стандарта XPath следующим образом:
//не подходит для /Потомок или-я:: node()/. Для Например, //para не подходит для /Потомок или-я:: node()/ребенок:: пункт и поэтому выберет любой элемент para в документ (даже элемент пара, который будет выбран элемент документа по //para, поскольку элемент документа node является потомком корня node); div//para не подходит для DIV/потомок или-я:: node()/ребенок:: пункт и поэтому выберет все параграфы потомки детей div.
Поскольку //
является коротким для /descendant-or-self::node()/
, он начинается с уровня документа, если вы не укажете node в начале.
Ответ 3
//C
- все C-узлы во всем документе
/E//C
будет только C-узлами под E
/C
будет только корнем C node
См. ссылка на синтаксис xpath
Ответ 4
В Спецификация XPATH вы найдете ниже 2.5 следующего утверждения:
//para выбирает весь параграф потомки корня документа и таким образом, выбирает все пара-элементы в тот же документ, что и контекст node
то есть. поведение, которое вы наблюдаете, действительно. Вы должны сделать что-то вроде "/E//C"