4

XDocument を使用して XML に書き込み ますが、この Qn のようにどこに書き込むかを知っています。

少しお役に立てば幸いです。XML ファイルを更新しようとしていますが、XML ファイルに書き込むメソッドを書くのに苦労しています。これはXMLファイルです

  <software>
    <software_entry name="Adobe Acrobat X Standard" path="Applications\Acrobat\Acrobat XStandard\AcroStan.msi" />
    ..
  </software>
  <ApplicationConfigurations>
     <Config name ="someName" value ="someValue"/>
      ..
  </ApplicationConfigurations>

ここで、ユーザーはタグを変更/追加できます。つまり、ユーザーは値を編集/追加できるため、software_entry の下の名前またはパスは不明です。フォーマットを除いて、すべてが不明です。

ファイルの読み取り、ファイルへの保存、DataTableグリッドへの入力などを行うことができます。LINQ を使用して

ただし、xmlへの書き込み中にテーブルを編集した後、私は立ち往生しています..

この種のデータをxmlに書き込むのを手伝ってくれる人はいますか?

私はこれまでにこれを試しました:

for (int i = 0; i < dt.Length; i++) //for every table 
{
      XName TableName = dt[i].TableName; //table name.

      XElement[] xInnerElt = new XElement[dt[i].Rows.Count]; //for n rows inside one table
      for (int j = 0; j < dt[i].Rows.Count; j++) //loop each tag inside the table
      {
         XName InnerTagName = htAtributNameForTable[dt[i].TableName].ToString(); //tag name form hash table. i.e, software_entry
         //I am unable to write the next line
         xInnerElt[j] = new XElement(InnerTagName,new XAttribute((XName)ColumnName,rows Item arry)),
         //loop till all column added
      }

      XElement xElt = new XElement(TableName, xInnerElt); //one table aded to tag.
}
4

3 に答える 3

3

この拡張メソッドを使用すると、任意のものを次のように変換できDataTableますXElement:

public static class Extensions
{
    public static XElement ToXml(this DataTable table, string rowElementName)
    {
        // check if table has name and rowElementName is not empty           

        return new XElement(
            new XElement(table.TableName,
                from row in table.AsEnumerable()
                select new XElement(rowElementName,
                    from column in table.Columns.Cast<DataColumn>()
                    let value = row.Field<string>(column)
                    where value != null
                    select new XAttribute(column.Caption, value)
                    )
                )
            );
    }
}

使用法:

DataTable table = new DataTable("software");
table.Columns.Add("name");
table.Columns.Add("path");
// add rows to table

XElement software = table.ToXml("software_element");
于 2013-03-14T14:01:46.987 に答える
2

問題:

結果のXMLに属性を作成する内部要素を追加する方法がわからないことをコメントで述べています。このビットを除いて、コードの残りの部分は完全に機能します。

 //I am unable to write the next line
     xInnerElt[j] = new XElement(InnerTagName,new XAttribute((XName)ColumnName,rows Item arry)),

ソリューション

不足している部分は、にある列をループしてから、DataTable行ごとに列の値にアクセスすることです。これは、DataRowオブジェクトが列名に関する情報を持っていないためです。

DataTable.Columnsしたがって、コレクションを介して別の内部ループが必要であり、DataRow列アクセサーdt.Rows[j][column]を使用して現在の列から値を取得します。

次のようになります。

              foreach (var column in dt[i].Columns)
              {
                  xInnerElt[j].Add(
                      new XAttribute(
                          (column as DataColumn).ColumnName,
                          dt[i].Rows[j][(column as DataColumn)].ToString()
                      )
                  );
              }

あなたのコードを使った私のテスト:

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

namespace XElemFromDT
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, string> htAtributNameForTable = new Dictionary<string, string>()
            {
                { "Software", "software_entry" },
                { "ApplicationConfigurations", "config" }
            };

            DataTable dt1 = new DataTable();
            dt1.TableName = "Software";
            dt1.Columns.Add("name", typeof(string));
            dt1.Columns.Add("path", typeof(string));
            dt1.Rows.Add("Adobe Acrobat X Standard", @"Applications\Acrobat\Acrobat XStandard\AcroStan.msi");
            dt1.Rows.Add("Adobe Photoshop", @"Applications\Photoshop\Photoshop.msi");

            DataTable dt2 = new DataTable();
            dt2.TableName = "ApplicationConfigurations";
            dt2.Columns.Add("name", typeof(string));
            dt2.Columns.Add("value", typeof(string));
            dt2.Rows.Add("someName", "someValue");
            dt2.Rows.Add("someOtherName", "someOtherValue");

            DataTable[] dt = new DataTable[] { dt1, dt2 };

            XDocument xDoc = new XDocument(new XElement("Root"));

            for (int i = 0; i < dt.Length; i++) //for every table 
            {

                  XName TableName = dt[i].TableName; //table name.

                  XElement[] xInnerElt = new XElement[dt[i].Rows.Count]; //for n rows inside one table
                  for (int j = 0; j < dt[i].Rows.Count; j++) //loop each tag inside the table
                  {
                     XName InnerTagName = htAtributNameForTable[dt[i].TableName].ToString(); //tag name form hash table. i.e, software_entry
                     //I am unable to write the next line
                     xInnerElt[j] = new XElement(InnerTagName);

                      foreach (var column in dt[i].Columns)
                      {
                          xInnerElt[j].Add(
                              new XAttribute(
                                  (column as DataColumn).ColumnName,
                                  dt[i].Rows[j][(column as DataColumn)].ToString()
                              )
                          );
                      }
                  }

                  XElement xElt = new XElement(TableName, xInnerElt); //one table aded to tag.
                  xDoc.Root.Add(xElt);
            }

            Console.WriteLine(xDoc.ToString());
            Console.ReadKey();
        }
    }
}

ボーナス -- 私はこれを試さなければならなかったので

LINQ を完全に使用してそれを行う方法は次のとおりです: (前の例と同じテスト データを使用)

    DataTable[] dt = new DataTable[] { dt1, dt2 };

    XDocument xDoc = new XDocument(new XElement("Root"));

    Func<DataTable, DataRow, IEnumerable<XAttribute>> getAttributes = (t, r) =>
        t.Columns.OfType<DataColumn>().Select(c => new XAttribute(c.ColumnName, r[c].ToString()));

    Func<DataTable, IEnumerable<XElement>> getElements = t =>
        t.Rows.OfType<DataRow>().Select(r => new XElement(htAtributNameForTable[t.TableName], getAttributes(t, r)));

    Func<DataTable[], IEnumerable<XElement>> getTables = dtc =>
        dtc.AsEnumerable().Select(t => new XElement(t.TableName, getElements(t)));

    xDoc.Root.Add(getTables(dt));
于 2013-03-14T12:20:42.423 に答える
1

XElements をファイルにストリーミングする方法を探しているだけなら、それは非常に簡単です。

        using (XmlWriter writer = XmlWriter.Create("filename.xml"))
        {
            writer.WriteStartElement("DocumentElementName");
            // Your code goes here
            xElt.WriteTo(writer);
            writer.WriteEndElement();
        }
于 2013-03-14T12:08:18.983 に答える