515

この XML ドキュメントを逆シリアル化する方法:

<?xml version="1.0" encoding="utf-8"?>
<Cars>
  <Car>
    <StockNumber>1020</StockNumber>
    <Make>Nissan</Make>
    <Model>Sentra</Model>
  </Car>
  <Car>
    <StockNumber>1010</StockNumber>
    <Make>Toyota</Make>
    <Model>Corolla</Model>
  </Car>
  <Car>
    <StockNumber>1111</StockNumber>
    <Make>Honda</Make>
    <Model>Accord</Model>
  </Car>
</Cars>

私はこれを持っています:

[Serializable()]
public class Car
{
    [System.Xml.Serialization.XmlElementAttribute("StockNumber")]
    public string StockNumber{ get; set; }

    [System.Xml.Serialization.XmlElementAttribute("Make")]
    public string Make{ get; set; }

    [System.Xml.Serialization.XmlElementAttribute("Model")]
    public string Model{ get; set; }
}

.

[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
    [XmlArrayItem(typeof(Car))]
    public Car[] Car { get; set; }

}

.

public class CarSerializer
{
    public Cars Deserialize()
    {
        Cars[] cars = null;
        string path = HttpContext.Current.ApplicationInstance.Server.MapPath("~/App_Data/") + "cars.xml";

        XmlSerializer serializer = new XmlSerializer(typeof(Cars[]));

        StreamReader reader = new StreamReader(path);
        reader.ReadToEnd();
        cars = (Cars[])serializer.Deserialize(reader);
        reader.Close();

        return cars;
    }
}

それはうまくいかないようです:-(

4

17 に答える 17

475

xmlをファイルに保存し、xsdを使用してC#クラスを生成するのはどうですか?

  1. ファイルをディスクに書き込みます(私はそれをfoo.xmlと名付けました)
  2. xsdを生成します。xsd foo.xml
  3. C#を生成します。xsd foo.xsd /classes

XmlSerializerEt voila-および:を介してデータを読み取ることができるはずのC#コードファイル

    XmlSerializer ser = new XmlSerializer(typeof(Cars));
    Cars cars;
    using (XmlReader reader = XmlReader.Create(path))
    {
        cars = (Cars) ser.Deserialize(reader);
    }

(生成されたfoo.csをプロジェクトに含めます)

于 2008-12-12T22:44:21.357 に答える
384

これが動作中のバージョンです。xmlではStockNumber、Make、Modelの値が要素であり、属性ではないため、XmlElementAttributeラベルをに変更しました。また、 (その関数はストリーム全体を読み取り、文字列を返すため、関数はリーダーを使用できなくなりました...位置はストリームの最後にありました)XmlElementも削除しました。私はまた、ネーミングでいくつかの自由を取りました:)。reader.ReadToEnd();Deserialize()

クラスは次のとおりです。

[Serializable()]
public class Car
{
    [System.Xml.Serialization.XmlElement("StockNumber")]
    public string StockNumber { get; set; }

    [System.Xml.Serialization.XmlElement("Make")]
    public string Make { get; set; }

    [System.Xml.Serialization.XmlElement("Model")]
    public string Model { get; set; }
}


[Serializable()]
[System.Xml.Serialization.XmlRoot("CarCollection")]
public class CarCollection
{
    [XmlArray("Cars")]
    [XmlArrayItem("Car", typeof(Car))]
    public Car[] Car { get; set; }
}

デシリアライズ関数:

CarCollection cars = null;
string path = "cars.xml";

XmlSerializer serializer = new XmlSerializer(typeof(CarCollection));

StreamReader reader = new StreamReader(path);
cars = (CarCollection)serializer.Deserialize(reader);
reader.Close();

そして、わずかに調整されたxml(<Cars>をラップするために新しい要素を追加する必要がありました... Netは配列の逆シリアル化に気を配っています):

<?xml version="1.0" encoding="utf-8"?>
<CarCollection>
<Cars>
  <Car>
    <StockNumber>1020</StockNumber>
    <Make>Nissan</Make>
    <Model>Sentra</Model>
  </Car>
  <Car>
    <StockNumber>1010</StockNumber>
    <Make>Toyota</Make>
    <Model>Corolla</Model>
  </Car>
  <Car>
    <StockNumber>1111</StockNumber>
    <Make>Honda</Make>
    <Model>Accord</Model>
  </Car>
</Cars>
</CarCollection>
于 2008-12-12T22:40:18.637 に答える
257

2 つの可能性があります。

方法 1. XSDツール


XML ファイルがこの場所にあるとします。C:\path\to\xml\file.xml

  1. 開発者コマンド プロンプトを開く または、Windows 8 を使用している場合は、スタート画面で開発者コマンド プロンプト
    の入力を開始でき ます。Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools
  2. 次のように入力して、場所を XML ファイル ディレクトリに変更します。cd /D "C:\path\to\xml"
  3. 次のように入力して、xml ファイルからXSD ファイルを作成します。xsd file.xml
  4. 入力してC# クラスを作成するxsd /c file.xsd

以上です!xml ファイルから C# クラスを生成しました。C:\path\to\xml\file.cs

方法 2 - 特殊貼り付け


必須の Visual Studio 2012 以降

  1. XML ファイルのコンテンツをクリップボードにコピーする
  2. ソリューションに新しい空のクラス ファイルを追加します ( Shift+ Alt+ C)
  3. そのファイルを開き、メニューでクリックしますEdit > Paste special > Paste XML As Classes
    ここに画像の説明を入力

以上です!

使用法


このヘルパー クラスを使用すると、使い方は非常に簡単です。

using System;
using System.IO;
using System.Web.Script.Serialization; // Add reference: System.Web.Extensions
using System.Xml;
using System.Xml.Serialization;

namespace Helpers
{
    internal static class ParseHelpers
    {
        private static JavaScriptSerializer json;
        private static JavaScriptSerializer JSON { get { return json ?? (json = new JavaScriptSerializer()); } }

        public static Stream ToStream(this string @this)
        {
            var stream = new MemoryStream();
            var writer = new StreamWriter(stream);
            writer.Write(@this);
            writer.Flush();
            stream.Position = 0;
            return stream;
        }


        public static T ParseXML<T>(this string @this) where T : class
        {
            var reader = XmlReader.Create(@this.Trim().ToStream(), new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
            return new XmlSerializer(typeof(T)).Deserialize(reader) as T;
        }

        public static T ParseJSON<T>(this string @this) where T : class
        {
            return JSON.Deserialize<T>(@this.Trim());
        }
    }
}

あなたが今しなければならないのは、次のことだけです:

    public class JSONRoot
    {
        public catalog catalog { get; set; }
    }
    // ...

    string xml = File.ReadAllText(@"D:\file.xml");
    var catalog1 = xml.ParseXML<catalog>();

    string json = File.ReadAllText(@"D:\file.json");
    var catalog2 = json.ParseJSON<JSONRoot>();
于 2013-10-27T02:11:51.067 に答える
101

次のスニペットでうまくいくはずです (シリアライゼーション属性のほとんどは無視できます)。

public class Car
{
  public string StockNumber { get; set; }
  public string Make { get; set; }
  public string Model { get; set; }
}

[XmlRootAttribute("Cars")]
public class CarCollection
{
  [XmlElement("Car")]
  public Car[] Cars { get; set; }
}

...

using (TextReader reader = new StreamReader(path))
{
  XmlSerializer serializer = new XmlSerializer(typeof(CarCollection));
  return (CarCollection) serializer.Deserialize(reader);
}
于 2008-12-22T22:24:49.340 に答える
25

これが役立つかどうかを確認してください:

[Serializable()]
[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
    [XmlArrayItem(typeof(Car))]
    public Car[] Car { get; set; }
}

.

[Serializable()]
public class Car
{
    [System.Xml.Serialization.XmlElement()]
    public string StockNumber{ get; set; }

    [System.Xml.Serialization.XmlElement()]
    public string Make{ get; set; }

    [System.Xml.Serialization.XmlElement()]
    public string Model{ get; set; }
}

失敗した場合は、Visual Studio に付属の xsd.exe プログラムを使用してその xml ファイルに基づいてスキーマ ドキュメントを作成し、それを使用してスキーマ ドキュメントに基づいてクラスを作成します。

于 2008-12-12T22:09:59.400 に答える
11

.net が「配列のデシリアライズにうるさい」とは思いません。最初の xml ドキュメントの形式が正しくありません。あるように見えますが、ルート要素はありません。正規の xml ドキュメントには、ルートと少なくとも 1 つの要素 (存在する場合) があります。あなたの例では:

<Root> <-- well, the root
  <Cars> <-- an element (not a root), it being an array
    <Car> <-- an element, it being an array item
    ...
    </Car>
  </Cars>
</Root>
于 2012-01-26T12:06:48.133 に答える
9

.xml ファイルがディスクのどこかに生成されていて、次のコードを使用している場合は、このコード ブロックを試してくださいList<T>

//deserialization

XmlSerializer xmlser = new XmlSerializer(typeof(List<Item>));
StreamReader srdr = new StreamReader(@"C:\serialize.xml");
List<Item> p = (List<Item>)xmlser.Deserialize(srdr);
srdr.Close();`

注:C:\serialize.xmlは私の .xml ファイルのパスです。必要に応じて変更できます。

于 2013-10-07T11:06:07.333 に答える
7

現実の世界では、元の XML をニーズに合わせて変更できないことが多いという事実を除けば、Kevin の回答は優れています。

元の XML に対する簡単な解決策もあります。

[XmlRoot("Cars")]
public class XmlData
{
    [XmlElement("Car")]
    public List<Car> Cars{ get; set; }
}

public class Car
{
    public string StockNumber { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
}

そして、あなたは単に呼び出すことができます:

var ser = new XmlSerializer(typeof(XmlData));
XmlData data = (XmlData)ser.Deserialize(XmlReader.Create(PathToCarsXml));
于 2018-01-13T14:11:38.143 に答える
1

xsd ファイルを作成するために xsd.exe を使用してエラーが発生した場合は、 msdn で説明されているようXmlSchemaInference クラスを使用します。実証する単体テストを次に示します。

using System.Xml;
using System.Xml.Schema;

[TestMethod]
public void GenerateXsdFromXmlTest()
{
    string folder = @"C:\mydir\mydata\xmlToCSharp";
    XmlReader reader = XmlReader.Create(folder + "\some_xml.xml");
    XmlSchemaSet schemaSet = new XmlSchemaSet();
    XmlSchemaInference schema = new XmlSchemaInference();

    schemaSet = schema.InferSchema(reader);


    foreach (XmlSchema s in schemaSet.Schemas())
    {
        XmlWriter xsdFile = new XmlTextWriter(folder + "\some_xsd.xsd", System.Text.Encoding.UTF8);
        s.Write(xsdFile);
        xsdFile.Close();
    }
}

// now from the visual studio command line type: xsd some_xsd.xsd /classes
于 2014-10-16T20:39:54.827 に答える
1

Cars car プロパティの 1 つの属性を XmlArrayItem から XmlElment に変更するだけです。つまり、から

[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
    [XmlArrayItem(typeof(Car))]
    public Car[] Car { get; set; }
}

[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
    [XmlElement("Car")]
    public Car[] Car { get; set; }
}
于 2014-11-17T05:20:35.707 に答える