【问题标题】:How to populate xml from list of paths如何从路径列表中填充 xml
【发布时间】:2013-05-21 11:35:38
【问题描述】:

如何从 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>

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

【问题讨论】:

    标签: c# xml string list path


    【解决方案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;
                    }
                }
            }
    

    【讨论】:

      【解决方案2】:

      我想我以前见过这样的问题... :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 的答案来解决您现在正在尝试的问题。

      【讨论】:

        猜你喜欢
        • 2010-11-12
        • 2015-05-13
        • 1970-01-01
        • 1970-01-01
        • 2014-12-25
        • 2011-09-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多