Допустим, у вас есть экземпляр XmlNode с именем node
для начала. Затем следующий код даст вам последний потомок последнего потомка первого потомка пра-прародителя этого узла:
XmlNode wantedNode = node.ParentNode.ParentNode.ParentNode.FirstChild.LastChild.LastChild;
Обратите внимание, что с этим кодом может пойти не так много вещей. Если какой-либо из упомянутых узлов окажется пустым, у вас появится исключение NullReferenceException. Таким образом, вы хотите сделать нулевую проверку на каждом уровне:
XmlNode wantedNode;
if (node.ParentNode != null && node.ParentNode.ParentNode != null /* and so on through the full path */)
{
wantedNode = node.ParentNode.ParentNode.ParentNode.FirstChild.LastChild.LastChild;
}
Давайте рассмотрим это на более конкретном примере. Предположим, у нас есть следующий XML-документ:
<?xml version="1.0" encoding="utf-8" ?>
<root>
<greatgrandparent>
<grandparent>
<parent id="1">
<child somevalue="3"></child>
</parent>
<parent id="2">
<child somevalue="4"></child>
<child somevalue="5"></child>
</parent>
</grandparent>
</greatgrandparent>
</root>
Если я правильно понимаю ваш вопрос, если мы начнем с узла <child somevalue="3"></child>
, мы хотим перейти к <child somevalue="5"></child>
. Пример кода выше сделает это. Однако, как уже упоминалось, он склонен давать исключения, если присутствуют не все ожидаемые узлы.
Даже если вы сказали, что вам нужен код на C #, а не XPath, в этом случае я чувствую, что XPath - это путь. Есть несколько способов решить эту проблему. Например, если узлы имеют разные имена тегов (как в моем примере документа), вместо этого вы можете сделать так:
XmlNode wantedNode = node.SelectSingleNode("ancestor::greatgrandparent/grandparent[position()=1]/parent[position()=last()]/child[position()=last()]");
if (wantedNode != null)
{
// the path was found
}
Это, конечно, при условии, что node
не является нулевым, но допустимым экземпляром XmlNode.
Разбивка выражения XPath:
- ancestor :: greatgrandparent -> это найдет любой узел с именем "greatgrandparent", который находится в любом месте вверх по иерархии (так что любой родитель, родитель и т. Д.)
- / grandparent [position () = 1] -> первый дочерний узел с именем «grandparent»
- / parent [position () = last ()] -> последний дочерний узел с именем «parent»
- / child [position () = last ()] -> последний дочерний узел с именем "child"
Если вы хотите почитать о том, как работают оси XPath, есть некоторая информация на w3schools.com .