2016-07-05 1 views
2

:ファイル名、ファイルサイズと親フォルダ名:取得データ

<folders> 
    <Folder> 
    <Folder_name>test</Folder_name> 
    <Number_of_files>2</Number_of_files> 
    <File> 
     <File_name>DTLite4461-0327</File_name> 
     <File_size_in_bytes>14682176</File_size_in_bytes> 
    </File> 
    <File> 
     <File_name>TeamViewer_Setup-ioh</File_name> 
     <File_size_in_bytes>11057224</File_size_in_bytes> 
    </File> 
    </Folder> 
    <Folder> 
    <Folder_name>podFolder1</Folder_name> 
    <Number_of_files>1</Number_of_files> 
    <File> 
     <File_name>npp.6.9.1.Installer</File_name> 
     <File_size_in_bytes>4203840</File_size_in_bytes> 
    </File> 
    </Folder> 
    <Folder> 
    <Folder_name>podFolder2</Folder_name> 
    <Number_of_files>1</Number_of_files> 
    <File> 
     <File_name>d-470sqe</File_name> 
     <File_size_in_bytes>2582112256</File_size_in_bytes> 
    </File> 
    </Folder> 
</folders> 

は、私は3つの列を持つグリッドビューでそれを印刷したいです。

私は、すべてのノードからすべてのデータを得ることができますが、私はこのようにしようとした

適切な親フォルダ名と適切なサイズにファイル名を接続するために取得することはできません。このコードで

XmlDocument doc = new XmlDocument(); 
doc.Load(xPath); 

XmlNodeList folderNodes = doc.SelectNodes(@"/folders/Folder"); 
int brojac = 0; 

foreach (XmlNode folderNode in folderNodes) 
{ 
    XmlNodeList fileNameNodes = doc.SelectNodes(@"/folders/Folder/File/File_name"); 
    XmlNodeList fileSizeNodes = doc.SelectNodes(@"/folders/Folder/File/Size"); 

    foreach (XmlNode fileName in fileNameNodes) 
    { 
     dgvXML.Rows.Add(fileName.InnerText, folderNode.InnerText, ""); 
    } 
} 

それは親フォルダ名を正しく出力しますが、毎回すべてのファイルを取得し、ファイルサイズに接続できません。これを行うための最善の方法がある

> File name ----------- Parent folder name ------ File size 
> DTLite4461-0327  test      14682176 
> TeamViewer_Setup-ioh test      11057224 
> npp.6.9.1.Installer podFolder1    4203840  
> d-470sqe    podFolder2    2582112256 

私はグリッドビューでこのような何かを取得したいですか?

+0

私はすでに[類似の質問](http://stackoverflow.com/questions/35585310/get-nested-elements-on-xml-with-lambda-and-set-to-listobject)に回答していました。それらを得ることができるように '':私の提案は、 '' ノードとに '' サブノードを追加することです。 –

答えて

1

あなたがこれを行う最善の方法を尋ねて以来、私はあなたの人生を信じられないほど楽にしてくれるpaste special機能を使用することをお勧めします。

基本的には、xmlのサンプルをコピーし、特殊なペーストを使用してクラスを作成し、xmlserializerを使用してオブジェクトまたはオブジェクトの配列を逆シリアル化します。それはすべてmsdnリンクで完全に説明されています。気に入ると思います。

EDITあなたが抱えているので、問題:

をデシリアライズするには、実行します。

using (XmlSerializer serializer = new XmlSerializer(typeof(folders))) 
{ 
    StreamReader myReader = new StreamReader(path_to_xml_goes_here); 
    folders foldersObject = (folders)serializer.Deserialize(myReader); 
    // Do stuff with the objects here 
} 

XMLクラス:

/// <remarks/> 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)] 
public partial class folders 
{ 

    private foldersFolder[] folderField; 

    /// <remarks/> 
    [System.Xml.Serialization.XmlElementAttribute("Folder")] 
    public foldersFolder[] Folder 
    { 
     get 
     { 
      return this.folderField; 
     } 
     set 
     { 
      this.folderField = value; 
     } 
    } 
} 

/// <remarks/> 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 
public partial class foldersFolder 
{ 

    private string folder_nameField; 

    private byte number_of_filesField; 

    private foldersFolderFile[] fileField; 

    /// <remarks/> 
    public string Folder_name 
    { 
     get 
     { 
      return this.folder_nameField; 
     } 
     set 
     { 
      this.folder_nameField = value; 
     } 
    } 

    /// <remarks/> 
    public byte Number_of_files 
    { 
     get 
     { 
      return this.number_of_filesField; 
     } 
     set 
     { 
      this.number_of_filesField = value; 
     } 
    } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlElementAttribute("File")] 
    public foldersFolderFile[] File 
    { 
     get 
     { 
      return this.fileField; 
     } 
     set 
     { 
      this.fileField = value; 
     } 
    } 
} 

/// <remarks/> 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 
public partial class foldersFolderFile 
{ 

    private string file_nameField; 

    private uint file_size_in_bytesField; 

    /// <remarks/> 
    public string File_name 
    { 
     get 
     { 
      return this.file_nameField; 
     } 
     set 
     { 
      this.file_nameField = value; 
     } 
    } 

    /// <remarks/> 
    public uint File_size_in_bytes 
    { 
     get 
     { 
      return this.file_size_in_bytesField; 
     } 
     set 
     { 
      this.file_size_in_bytesField = value; 
     } 
    } 
} 
+0

ありがとうございましたが、私は質問で入力した私のXMLのために働いていません。 – Zorge

+1

@Bopa私はちょうど試して、それは完全に働いた。私は答えを更新します – Gaspa79

0

てみたXML LINQ:まあ

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Xml; 
using System.Xml.Linq; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     const string FILENAME = @"c:\temp\test.xml"; 
     public Form1() 
     { 
      InitializeComponent(); 
      DataTable dt = new DataTable(); 
      dt.Columns.Add("File Name", typeof(string)); 
      dt.Columns.Add("File Size", typeof(string)); 
      dt.Columns.Add("Parent", typeof(string)); 

      XDocument doc = XDocument.Load(FILENAME); 
      foreach (XElement folder in doc.Descendants("Folder").AsEnumerable()) 
      { 
       string folder_name = folder.Element("Folder_name").Value; 
       foreach (XElement file in folder.Descendants("File").AsEnumerable()) 
       { 
        dt.Rows.Add(new object[] { 
         file.Element("File_name").Value, 
         file.Element("File_size_in_bytes").Value, 
         folder_name 
        }); 

       } 
      } 
      dataGridView1.DataSource = dt; 
     } 
    } 
} 
1

... FileFilesのように "grouping"要素内にないので、XML構造体を再考する必要があります。 XML構造は、次のようになります。

もちろん
Folders 
    +-Folder 
     +-Files (you missed that) 
     +-File 

、そこにそれを回避するための方法ですが、代わりにXmlDocumentXDocument class + LiqToXmlを使用する必要があります。

は例を見てみましょう:

string xcontent = @"<?xml version='1.0' ?>..."; //replace ... with xml content 
//i decided to not post entire content of xml due to clarity of code 

XDocument xdoc = XDocument.Parse(xcontent); 
var data = xdoc.Descendants("Folder") 
       .Select(x=> new 
        { 
         FolderName = x.Element("Folder_name").Value, 
         Files = x.Descendants("File") 
         .Select(a=> 
          Tuple.Create(
           a.Element("File_name").Value, 
           a.Element("File_size_in_bytes").Value) 
         ).ToList() 
        }) 
       .SelectMany(x=>x.Files. 
        Select(y=> new 
        { 
         FolderName =x.FolderName, 
         FileName = y.Item1, 
         FileSize=y.Item2 
        })) 
       .ToList(); 

結果:

FolderName FileName    FileSize 
test  DTLite4461-0327  14682176 
test  TeamViewer_Setup-ioh 11057224 
podFolder1 npp.6.9.1.Installer 4203840 
podFolder2 d-470sqe    2582112256 

dateクエリ?

最初にselectステートメントはフォルダ名を取得し、ファイルのリストはそのフォルダに属します。この方法:

FolderName | Files(a list) 
--------------------------------------------------- 
test  | Item1(FileName)  Item2(FileSize) 
      |-------------------------------------- 
      | DTLite4461-0327  14682176 
      | TeamViewer_Setup-ioh 11057224 
---------------------------------------------------- 
...  | ... (and so on) 

第二select文は(SelectMany)上記のデータを取得し、先の結果セットにそれらを転置します。

試してみてください!