如何从路径列表中填充xml

时间:2013-05-21 11:35:39

标签: c# xml string list path

如何从C#中的路径列表中填充XML?

例如:

C:\WINDOWS\addins
C:\WINDOWS\AppPatch
C:\WINDOWS\AppPatch\MUI
C:\WINDOWS\AppPatch\MUI\040C
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MUI
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MUI\0409

作为输入列表,输出应为:

<node label="C:">
   <node label="WINDOWS">
      <node label="AppPatch">
         <node label="MUI">
            <node label="040C" />
         </node>
      </node>
      <node label="Microsoft.NET">
         <node label="Framework">
            <node label="v2.0.50727">
               <node label="MUI">
                  <node label="0409" />
               </node>
            </node>
         </node>
      </node>
      <node label="addins" />
   </node>
</node>

有人可以帮我解决这个问题,我试图这样做一个多星期没有结果吗?

2 个答案:

答案 0 :(得分:1)

这听起来像是家庭作业,但嘿,这是你的未来。 ;)

var paths = new string[] 
        {
            "C:\\WINDOWS\\addins",
            "C:\\WINDOWS\\AppPatch",
            "C:\\WINDOWS\\AppPatch\\MUI",
            "C:\\WINDOWS\\AppPatch\\MUI\\040C",
            "C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727",
            "C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727\\MUI",
            "C:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727\\MUI\\0409"
        };

        const string node = "node";
        const string label = "label";

        var xml = new XElement("nodes");

        foreach (var path in paths)
        {
            var labelValues = path.Split('\\');
            var currentNode = xml;

            foreach (var labelValue in labelValues)
            {
                var foundNode = currentNode.Elements(node).Where(n => (string)n.Attribute(label) == labelValue).SingleOrDefault();
                if (foundNode != null)
                {
                    currentNode = foundNode;
                }
                else
                {
                    var newNode = new XElement(node, new XAttribute(label, labelValue));
                    currentNode.Add(newNode);
                    currentNode = newNode;
                }
            }
        }

答案 1 :(得分:0)

我想我之前看过这样的问题......:P 好吧,也许这会做你想要的:

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Linq;

namespace WhateverMakesSense
{
    public class PathsToXml
    {
        private XDocument xDoc;
        private readonly Dictionary<string, XElement> xElements = new Dictionary<string, XElement>();

        public XDocument GetXDocument(IEnumerable<string> paths)
        {
            xDoc = new XDocument();

            foreach (var path in paths)
            {
                getElement(path);
            }

            return xDoc;
        }

        private XElement getElement(string path)
        {
            if (xElements.ContainsKey(path))
            {
                return xElements[path];
            }

            var di = new DirectoryInfo(path);
            var fullName = di.FullName;

            if (di.Parent == null)
            {
                xElements[fullName] = new XElement("node",
                    new XAttribute("label", fullName),
                    new XAttribute("fullpath", fullName));
                xDoc.Add(xElements[fullName]);
                return xElements[fullName];
            }

            var parent = getElement(di.Parent.FullName);
            var innerMost = Path.GetFileName(fullName) ?? string.Empty;

            xElements[fullName] = new XElement("node",
                new XAttribute("label", innerMost),
                new XAttribute("fullpath", fullName));
            parent.Add(xElements[fullName]);
            return xElements[fullName];
        }

        public static IList<string> PathSplit(string path)
        {
            var ret = pathSplit(path);
            ret.Reverse();
            return ret;
        }
        private static List<string> pathSplit(string path)
        {
            var ret = new List<string>();
            var innerMost = Path.GetFileName(path) ?? string.Empty;
            while (String.IsNullOrWhiteSpace(innerMost) == false)
            {
                var di = new DirectoryInfo(path);
                if (ReferenceEquals(null, di.Parent))
                {
                    break;
                }
                path = di.Parent.FullName;
                ret.Add(innerMost);
                innerMost = Path.GetFileName(path) ?? string.Empty;
            }
            ret.Add(path);
            return ret;
        }
    }
}

用法:var xDoc = new PathsToXml().GetXDocument(yourListOfPaths);

我觉得路径分裂很可怕,但它确实有效。


修改 抱歉!这是已删除的其他问题的答案,您仍然需要fullPath。使用@BasDL的答案来解决您现在正在尝试的问题。