2

xml 要素をオブジェクトにインポートするにはどうすればよいですか? 以下のコードは機能しません。SetValue で失敗し、その理由がわかりません。

しかし、それでも、linqにはこれを行うためのよりクリーンな方法があると思われますが、例が見つかりません。

class Printers {
    public List<Printer> list = new List<Printer>();

    public Printers()
    {
        var xDoc = XDocument.Load(Properties.Settings.Default.XmlSetupPath).Root;
        var xPrinters = xDoc.Element("printers").Elements();
        foreach (var xPrinter in xPrinters)
        {
            var printer = new Printer();
            foreach (var xEl in xPrinter.Elements())
            {
                printer.GetType().GetProperty(xEl.Name.ToString()).SetValue(printer, xEl.Value);
            }
        }

    }

}

class Printer
{
    public string name;
    public string ip;
    public string model;
    public string infx86;
    public string infx64;
    public string location;
    public string comment;
}

私のXML:

<printers>
 <printer>
  <name>my Printer</name>
  <ip>192.168.100.100</ip>
  <model>Brother</model>
  <driver>ab</driver>
  <infx86>ab\cd.INF</infx86>
  <comment>Copycenter</comment>
 </printer>
 <printer>
  <name>my Printer</name>
  <foobar>oh no!</foobar>
 </printer>
</printers>

したい

4

1 に答える 1

5

プロパティを求めていますが、タイプにはfieldsしかありません。次のように、それらをプロパティにします。

 public string name { get; set; }

...またはType.GetField代わりに使用します。

見栄えを良くするという点では、クラスに静的FromXElementメソッドを個人的に追加したいと思います。その時点で、次のことが可能になります。Printer

list = xDoc.Element("printers")
           .Elements()
           .Select(Printer.FromXElement)
           .ToList();

または、新しいインスタンスを作成し、リフレクションを介してそれを設定するジェネリック メソッドを作成することもできます。

public static T FromXElement<T>(XElement element) where T : class, new()
{
    T value = new T();
    foreach (var subElement in element.Elements())
    {
        var field = typeof(T).GetField(subElement.Name.LocalName);
        field.SetValue(value, (string) subElement);
    }
    return value;
}

それで:

list = xDoc.Element("printers")
           .Elements()
           .Select(XmlReflection.FromXElement<Printer>)
           .ToList();
于 2013-09-20T15:27:12.043 に答える