2013-05-21 140 views
-1

如何從C#中的路徑列表填充XML?如何從路徑列表填充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> 

有人可以幫助我,我試圖做一個多星期都沒有結果?

回答

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的答案爲你正在嘗試的東西。

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; 
       } 
      } 
     }