C # - Структура каталогов из XML - PullRequest
0 голосов
/ 27 апреля 2018

Используя C #, у меня есть XML-файл, содержащий структуру папок, пользователь выбирает основную папку проекта, затем система начинает проверку подпапок в основной папке проекта на основе структуры XML-файла. Структура папок является динамической, поскольку администратор приложения может добавлять / удалять / изменять папку в структуре, изменяя файл XML.

Как пройтись по XML, я пытался использовать XmlDocument, чтобы получить полный путь к каталогу, но я читал об использовании XDocument для лучшего результата, но мои знания XML все еще являются базовыми.

Структура файла XML:

<?xml version="1.0" encoding="utf-8" ?>

<dir name="Site Documents">
  <dir name="External">
    <dir name="Mechanical">
      <dir name="01. Submittals">
        <dir name="1. Sent">
        </dir>
        <dir name="2. Received" />
      </dir>
      <dir name="02. Drawings">
        <dir name="1. Sent">
        </dir>
        <dir name="2. Received" />
      </dir>
      <dir name="03. MIR">
        <dir name="1. Sent">
        </dir>
        <dir name="2. Received" />
      </dir>
      <dir name="04. IR">
        <dir name="1. Sent">
        </dir>
        <dir name="2. Received" />
      </dir>
    </dir>
    <dir name="Electrical">
      <dir name="01. Submittals">
        <dir name="1. Sent">
        </dir>
        <dir name="2. Received" />
      </dir>
      <dir name="02. Drawings">
        <dir name="1. Sent">
        </dir>
        <dir name="2. Received" />
      </dir>
      <dir name="03. MIR">
        <dir name="1. Sent">
        </dir>
        <dir name="2. Received" />
      </dir>
      <dir name="04. IR">
        <dir name="1. Sent">
        </dir>
        <dir name="2. Received" />
      </dir>
    </dir>
  </dir>
  <dir name="Internal">
    <dir name="01. PR">
      <dir name="1. MECH">
      </dir>
      <dir name="2. ELEC" />
    </dir>
    <dir name="02. PO">
    </dir>
    <dir name="03. SRF">
    </dir>
    <dir name="04. RMR" />
  </dir>
</dir>

РЕДАКТИРОВАТЬ - 1

Я пытался использовать этот тестовый код, чтобы получить путь к узлу и подузлу

private void button2_Click(object sender, EventArgs e)
        {
            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(@"C:\Users\John_Doe\_data\directory_hirarchy.xml");
            XmlNodeList xmlFolderName = xDoc.SelectNodes("//dir");
            MessageBox.Show(xmlFolderName.Count.ToString());
            string finalText = "";
            for (int ctr = 0; ctr < xmlFolderName.Count; ctr++)
            {
                string DocFolder = xmlFolderName[ctr].Attributes["name"].InnerText;
                finalText = finalText + DocFolder + "\r\n";
            }
            txtDisplay.Text = finalText; // Test text box for Output Result
        }

Вывод текстового поля:

Site Documents External Mechanical 01. Submittals 1. Sent 2. Received 02. Drawings 1. Sent 2. Received 03. MIR 1. Sent 2. Received 04. IR 1. Sent 2. Received Electrical 01. Submittals 1. Sent 2. Received 02. Drawings 1. Sent 2. Received 03. MIR 1. Sent 2. Received 04. IR 1. Sent 2. Received Internal 01. PR 1. MECH 2. ELEC 02. PO 03. SRF 04. RMR

Решено Дейзи Шиптон

using System;
using System.Linq;
using System.Xml.Linq;

class Program
{
    static void Main()
    {
        var doc = XDocument.Load("test.xml");
        var directories = doc.Descendants("dir");

        foreach (var dir in directories)
        {
            var parts = dir
                .AncestorsAndSelf() // All the ancestors of this element, and itself
                .Reverse()          // Reversed (so back into document order)
                .Select(e => e.Attribute("name").Value); // Select the name
            var path = string.Join("/", parts);
            Console.WriteLine(path);
        }
    }   
}

1 Ответ

0 голосов
/ 27 апреля 2018

Здесь есть два варианта:

  • Используйте рекурсию, чтобы вы могли отслеживать "путь до сих пор"
  • Просто посмотрите на все элементы, но используйте их предков, чтобы построить путь

Первое, вероятно, проще всего понять, и да, использование LINQ to XML делает жизнь проще.

using System;
using System.Xml.Linq;

class Program
{
    static void Main()
    {
        var doc = XDocument.Load("test.xml");
        PrintDirectories(doc, null);        
    }

    static void PrintDirectories(XContainer parent, string path)
    {
        foreach (XElement element in parent.Elements("dir"))
        {
            string dir = element.Attribute("name").Value;
            string fullPath = path == null ? dir : $"{path}/{dir}";
            Console.WriteLine(fullPath);
            PrintDirectories(element, fullPath);
        }
    }
}

Нерекурсивный подход примерно такого же размера, но, возможно, его сложнее понять, если вы не знакомы с LINQ:

using System;
using System.Linq;
using System.Xml.Linq;

class Program
{
    static void Main()
    {
        var doc = XDocument.Load("test.xml");
        var directories = doc.Descendants("dir");

        foreach (var dir in directories)
        {
            var parts = dir
                .AncestorsAndSelf() // All the ancestors of this element, and itself
                .Reverse()          // Reversed (so back into document order)
                .Select(e => e.Attribute("name").Value); // Select the name
            var path = string.Join("/", parts);
            Console.WriteLine(path);
        }
    }   
}
...