Проверка дерева C #, если узел существует - PullRequest
1 голос
/ 23 мая 2011

Я пытаюсь заполнить древовидное представление из XmlDocument.Корень дерева установлен как «Сценарии», и от корня следующим уровнем должен быть «Отделы», который находится внутри XML-скрипта.Я могу получить данные из документа XML без проблем.Мой вопрос заключается в том, что при циклическом просмотре XmlDocument и добавлении узлов в корневой узел я хочу убедиться, что если отдел уже находится в древовидной структуре, он не будет добавлен снова.Я должен также добавить, что у каждого Департамента также есть список сценариев, которые должны быть дочерними узлами отдела.

Пока мой код:

        XmlDocument xDoc = new XmlDocument();
        xDoc.LoadXml(scriptInformation);
        TreeNode t1;
        TreeNode rootNode = new TreeNode("Script View");
        treeView1.Nodes.Add(rootNode);
        foreach (XmlNode node in xDoc.SelectNodes("//row"))
        {
            t1 = new TreeNode(node["DEPARTMENT"].InnerXml);
           //How to check if node already exists in treeview?



        }

Спасибо.

Ответы [ 8 ]

3 голосов
/ 23 мая 2011
if(treeView1.Nodes.ContainsKey("DEPARTMENT")){
//...
}

РЕДАКТИРОВАТЬ: рекурсивный метод:

 bool exists = false;
        foreach (TreeNode node in treeView1.Nodes) {
            if (NodeExists(node, "DEPARTMENT"))
                exists = true;
        }
    private bool NodeExists(TreeNode node, string key) {
        foreach (TreeNode subNode in node.Nodes) {
            if (subNode.Text == key) {
                return true;
            }
            if (node.Nodes.Count > 0) {
                NodeExists(node, key);
            }
        }
        return false;
    }
1 голос
/ 25 мая 2011

Я использую,

string department = node["DEPARTMENT"].InnerXml;
TreeNode node = parentNode.Nodes[department] ?? parentNode.Nodes.Add(department, department);

Эта строка гарантирует, что поиск отдела стоимости будет выполнен первым, если он не найден, он его создает.Вы должны сделать двойную запись в Add (), чтобы она имела ключевое значение, которое вы можете выполнить с помощью .Nodes[department].

1 голос
/ 23 мая 2011

Не уверен насчет структуры документа ...
Не могли бы вы использовать Linq to Xml, загрузить документ и получить отдельную строку (row = отдела?) И рассмотреть только эти элементы для создания TreeNode? Это эффективнее, чем пытаться найти, был ли уже добавлен узел с таким текстом. например:

 var rows =      (  from row  in XDocument.Load(document).Root.Elements("row")
                    select row
                 ).Distinct(new SampleElementComparerOnNameAttribute());

Здесь EqualityComparer создается для значения атрибута "name", предполагая, что структура документа равна

<rows><row name='dep1'><script>script1</script><script>script2</script></row><row name='dep1'><script>script3</script><script>script4</script></row></rows>
1 голос
/ 23 мая 2011

Если ваш XML-документ имеет заданную структуру, где «Отделы» всегда будут индексироваться в 1;

е:

index:[0] Scripts
    index:[1] Department
        index:[2] Script
    index:[1] Department2
        index:[2] Script

Затем вы можете инкапсулировать следующий код в метод, где 'name' является строковым параметром, а тип возвращаемого значения - логическим.

foreach (TreeNode node in uxTreeView.Nodes[0].Nodes) {
    if (node.Name.ToLower() == name.ToLower()) {
        return true;
    }
}
return false;

Идея состоит в том, что вы вызываете эту функцию каждый раз, когда сталкиваетесь с узлом 'Department' в своем XML, перед созданием TreeNode.

Полный пример:

private bool DepartmentNodeExists(string name) {
    foreach (TreeNode node in uxTreeView.Nodes[0].Nodes) {
        if (node.Name.ToLower() == name.ToLower()) {
            return true;
        }
    }
    return false;
}

Наконец, легкий способ:

private bool DepartmentNodeExists(string name) {
    if (uxTreeView.Nodes[0].ContainsKey(name)) {
        return true;
    }
    else {
        return false;
    }
}

Все они просто реорганизованы и инкапсулированы в свои собственные именованные методы, вы, конечно, можете просто вызвать:

if (uxTreeView.Nodes[0].ContainsKey(name)) {
    // do not create TreeNode
}

... во время анализа вашего XML. PS. Все эти примеры предполагают, что у вас уже есть первый корневой узел в TreeView, который добавлен в TreeView.

1 голос
/ 23 мая 2011

Вы можете сделать что-то вроде этого:

TreeNode parentNode = t1.Parent;
if (parentNode != null}
{
    if(parentNode.Nodes.Cast<TreeNode>().ToList().Find(t => t.Text.Equals(node["DEPARTMENT"].InnerXml) == null)
    {
        //Add node
    }
}
else
{
    bool isFound = true;
    if (treeView1.Nodes.Cast<TreeNode>().ToList().Find(t => t.Text.Equals(node["DEPARTMENT"].InnerXml) == null)
    {
        isFound = false;
    }

    if(!isFound)
    {
        //Add node
    }
}
1 голос
/ 23 мая 2011

В зависимости от размера вашего XML-файла, вы можете использовать ассоциированный List для быстрого поиска.Когда вы добавляете каждый узел в TreeView, добавляйте его и в List.

0 голосов
/ 23 мая 2011

Это зависит от структуры вашего ввода.Поскольку вы не показываете, как именно вы добавляете свои подузлы, я могу указать только на метод Contains или ContainsKey свойства Nodes , либо самого treeView1, либолюбые подузлы, которые вы добавляете.Вам следует использовать перегрузку метода Add, чтобы указать имя ключа для упрощения поиска.

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