Как найти конкретный узел XML? - PullRequest
0 голосов
/ 20 мая 2009

У меня есть эта проблема, чтобы найти конкретный узел XML, у меня есть эта проблема на stackoverflow, и некоторые приятели предложили xpath.

Я новичок в XML. пожалуйста, мне нужен код на C #, чтобы найти родителя, родителя, родителя как (великого прародителя), а затем первого потомка, lastchild, lastchild. код должен перебирать дерево вверх и вниз снова. Посмотрите много учебников по xpath онлайн.

Я обнаружил, что путь, как правило, специфичен для уже существующего конкретного узла. Программа, которая мне нужна, не получит никакого конкретного именованного узла, потому что при каждом проходе новый узел будет добавляться в дерево XML. Короче говоря, мне нужно найти базу узлов на ее позиции вдали от текущего узла

Я имел в виду поиск родительского родительского родителя текущего узла (великого великого родительского узла), затем найти первого потомка, затем найти последнего ребенка, последнего ребенка

keepkind of currentnode.parentnode.parentnode.parentnode.firstchild.lastchild.lastchild;

с использованием xpath C #

Ответы [ 2 ]

5 голосов
/ 20 мая 2009

Допустим, у вас есть экземпляр 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 .

2 голосов
/ 20 мая 2009

На все вопросы, которые вы задаете, отвечает класс XmlNode . У него есть свойства с именами ParentNode, FirstChild и LastChild, каждый из которых возвращает другое XmlNode.

Чтобы сделать то же самое в XPath, вы можете использовать сокращение "..", чтобы получить родительский узел, и "*[position()=1]" или "*[position()=last()]", чтобы получить первый и последний дочерний элемент, например:

XmlNode foundNode = node.SelectSingleNode("../../../*[position()=1]/*[position()=last()]/*[position()=last()]");

(Примечания: ".." - это сокращение от оси parent :: *, а "*" - это сокращение от оси "child :: *")

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...