XML文字列をオブジェクトに変換


179

ソケットを介してXML文字列を受信して​​いますが、これらをC#オブジェクトに変換したいと考えています。

メッセージの形式は次のとおりです。

<msg>
   <id>1</id>
   <action>stop</action>
</msg>

私は.Netを初めて使用するので、これを実行するためのベストプラクティスがわかりません。以前にJAXB for Javaを使用したことがあり、同様のものがあるかどうか、またはこれが別の方法で処理されるかどうかはわかりませんでした。


3
これらのオブジェクトはありますか、それとも動的にオブジェクトを生成したいですか?
Stephan


私にとってこれが最良の選択肢でした:stackoverflow.com/a/24184283/2647430
Ivan Lopez

回答:


277

xsd.exeWindows SDKとともに次のようなディレクトリにインストールされるツールを使用する必要があります。

C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin

そして64ビットのコンピュータでは:

C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\bin

そして、Windows 10コンピュータでは:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin

最初の実行ではxsd.exe、サンプルXML を使用してXSDファイル(XMLスキーマファイル)に変換します。

xsd yourfile.xml

これによりyourfile.xsd、2番目のステップでを使用xsd.exeしてC#クラスに再び変換できます。

xsd yourfile.xsd /c

これによりyourfile.cs、取得するXMLファイルを逆シリアル化するために使用できるC#クラスを含むファイルが得られます。

XmlSerializer serializer = new XmlSerializer(typeof(msg));
msg resultingMessage = (msg)serializer.Deserialize(new XmlTextReader("yourfile.xml"));

ほとんどの場合、問題なく機能するはずです。

更新: XMLシリアライザーは入力として任意のストリームを受け取ります-ファイルまたはメモリストリームのどちらでも問題ありません。

XmlSerializer serializer = new XmlSerializer(typeof(msg));
MemoryStream memStream = new MemoryStream(Encoding.UTF8.GetBytes(inputString));
msg resultingMessage = (msg)serializer.Deserialize(memStream);

またはStringReaderを使用します。

XmlSerializer serializer = new XmlSerializer(typeof(msg));
StringReader rdr = new StringReader(inputString);
msg resultingMessage = (msg)serializer.Deserialize(rdr);

詳しい説明ありがとうございます。私の場合、XMLはソケットを介して送信され、文字列です。XMLファイルの代わりに文字列を逆シリアル化するにはどうすればよいですか?
Steve

5
@Steve:StringReaderを開いて、Deserializeメソッドを渡すことができます。StringReaderはTextReaderから派生します。
Skurmedel

Linqを使用してファハドが言及したアプローチよりもあなたのアプローチを好むだろうか?
Steve

2
@Steve:はい、そうします-オブジェクトにデシリアライズしてオブジェクトのプロパティを突くことができるようにすることは、XML要素、属性、子ノードなどを大量に使用するよりもはるかに簡単です。Linq-to-XMLは、 XMLは不規則であり、常に変化するか、事前に認識されていません。
marc_s

7
このWebサイトは、xsdツールIMOよりもはるかに簡単です:xmltocsharp.azurewebsites.net
nasch

226

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

方法1. XSDツール


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

  1. 開いた 開発者は、コマンドプロンプト
    あなたにはそれを見つけることができますStart Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools あなただけの入力を開始することができますWindows 8の持っている場合、または開発者のコマンドプロンプトでのスタート画面
  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-特殊貼り付け


プロジェクトターゲットとして.Net Framework> = 4.5の必須のVisual Studio 2012+および「Windows Communication Foundation」個別コンポーネントがインストール

  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>();

7
乾杯。re:方法2、.net 4.5をターゲットにする必要があります。それ以外の場合、オプションは使用できません。
timB33 2013

12
方法2はとんでもなく便利です!それをありがとう。私はそれが存在することを知りませんでした。
Dominic Bindley

1
方法2の称賛は魅力のように機能します。退屈なクラスを実装する必要なく、プログラムでXMLを単純に解析しようとする場合に最適です。
Alex

1
最初の方法として「形式を選択して貼り付け」を行う必要があります。これが最も簡単な方法です。制限」の.NET Framework> = 4.5"は、2017年には重要ではありません
マイケルFreidgeim

2
「XMLをクラスとして貼り付ける」には、Visual StudioがインストールされたWCFワークロードが必要です。
Lennart 2017年

49

このメソッドを試して、Xmlをオブジェクトに変換します。それはあなたがやっていることのために作られています:

protected T FromXml<T>(String xml)
{
    T returnedXmlClass = default(T);

    try
    {
        using (TextReader reader = new StringReader(xml))
        {
            try
            {
                returnedXmlClass = 
                    (T)new XmlSerializer(typeof(T)).Deserialize(reader);
            }
            catch (InvalidOperationException)
            {
                // String passed is not XML, simply return defaultXmlClass
            }
        }
    }
    catch (Exception ex)
    {
    }

    return returnedXmlClass ;        
}

次のコードを使用して呼び出します。

YourStrongTypedEntity entity = FromXml<YourStrongTypedEntity>(YourMsgString);

6
=「」が>期待されていなかった。このエラーのxmlnsを手に入れた"}、任意のアイデアを。?
のPrashant

問題は、事前にクラスを完璧に形成する必要があることです。多分XMLが与えられたときにクラスを出力する関数ですか?xsd.exeがヒット&ミス(主に複雑なものではミス)...
小泉由美

1
ああ、神様は.nets xmlシリアライザーの処理に何時間も費やしましたが、これはすぐに機能しました。
クリストファークラーク2017年

11

Visual Studio 2013を管理者として実行する... Xmlファイルのコンテンツをコピーします。VisualStudio 2013>編集>形式を選択して貼り付け> XmlをC#クラスとして貼り付けに移動すると、Xmlファイルのコンテンツに従ってc#クラスが作成されます。


7

誰かがこれが役立つと思うかもしれないので念のため:

public static class XmlConvert
{
    public static string SerializeObject<T>(T dataObject)
    {
        if (dataObject == null)
        {
            return string.Empty;
        }
        try
        {
            using (StringWriter stringWriter = new System.IO.StringWriter())
            {
                var serializer = new XmlSerializer(typeof(T));
                serializer.Serialize(stringWriter, dataObject);
                return stringWriter.ToString();
            }
        }
        catch (Exception ex)
        {
            return string.Empty;
        }
    }

    public static T DeserializeObject<T>(string xml)
         where T : new()
    {
        if (string.IsNullOrEmpty(xml))
        {
            return new T();
        }
        try
        {
            using (var stringReader = new StringReader(xml))
            {
                var serializer = new XmlSerializer(typeof(T));
                return (T)serializer.Deserialize(stringReader);
            }
        }
        catch (Exception ex)
        {
            return new T();
        }
    }
}

あなたはそれを使ってそれを呼び出すことができます:

MyCustomObject myObject = new MyCustomObject();
string xmlString = XmlConvert.SerializeObject(myObject)
myObject = XmlConvert.DeserializeObject<MyCustomObject>(xmlString);

5

上記のようにクラスを生成するか、手動で記述できます。

[XmlRoot("msg")]
public class Message
{
    [XmlElement("id")]
    public string Id { get; set; }
    [XmlElement("action")]
    public string Action { get; set; }
}

次に、ExtendedXmlSerializerを使用してシリアル化および逆シリアル化できます。

インスタレーション あなたはからExtendedXmlSerializerをインストールすることができますnugetまたは次のコマンドを実行します。

Install-Package ExtendedXmlSerializer

シリアル化:

var serializer = new ConfigurationContainer().Create();
var obj = new Message();
var xml = serializer.Serialize(obj);

逆シリアル化

var obj2 = serializer.Deserialize<Message>(xml);

このシリアライザーのサポート:

  • 標準XMLSerializerからのシリアライズxml
  • シリアライゼーションクラス、構造体、ジェネリッククラス、プリミティブタイプ、ジェネリックリストとディクショナリ、配列、列挙型
  • プロパティインターフェイスを持つシリアル化クラス
  • シリアル化循環参照と参照ID
  • 古いバージョンのxmlの逆シリアル化
  • プロパティの暗号化
  • カスタムシリアライザー
  • XmlElementAttributeとXmlRootAttributeをサポートする
  • POCO-すべての構成(移行、カスタムシリアライザー...)はクラス外です

ExtendedXmlSerializerは、.NET 4.5以降および.NET Coreをサポートしています。WebApiおよびAspCoreと統合できます。


1
素晴らしいポスト!ドキュメントgithub.com/wojtpl2/ExtendedXmlSerializer
user1477388


2

ダミアンの素晴らしい答えを単純化して、

public static T ParseXml<T>(this string value) where T : class
{
    var xmlSerializer = new XmlSerializer(typeof(T));
    using (var textReader = new StringReader(value))
    {
        return (T) xmlSerializer.Deserialize(textReader);
    }
}

1

DTOをCustomObjectとして作成する

以下のメソッドを使用して、JAXBを使用してXML文字列をDTOに変換します

private static CustomObject getCustomObject(final String ruleStr) {
    CustomObject customObject = null;
    try {
        JAXBContext jaxbContext = JAXBContext.newInstance(CustomObject.class);
        final StringReader reader = new StringReader(ruleStr);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        customObject = (CustomObject) jaxbUnmarshaller.unmarshal(reader);
    } catch (JAXBException e) {
        LOGGER.info("getCustomObject parse error: ", e);
    }
    return customObject;
}

0

xmlメッセージのxsdがある場合は、.Net xsd.exeツールを使用してc#クラスを生成できます。

この.Netクラスを使用して、xmlを生成できます。


0

ここでの他の回答に加えて、XML DOMのような読み取りのためのXmlDocumentクラス、または高速順方向専用リーダーであるXmlReaderを自然に使用して、「手動」でそれを行うことができます。


0

高度なxsdからc#クラス生成ツールを使用する別の方法:xsd2code.com。このツールは非常に便利で強力です。Visual Studioのxsd.exeツールよりも多くのカスタマイズが可能です。Xsd2Code ++は、リストまたは配列を使用するようにカスタマイズでき、多数のImportステートメントを含む大規模なスキーマをサポートします。

いくつかの機能のメモ、

  • XSDスキーマまたはXMLファイルから柔軟なC#またはVisual Basicコードにビジネスオブジェクトを生成します。
  • サポートフレームワーク2.0から4.x
  • 強力な型付きコレクション(List、ObservableCollection、MyCustomCollection)をサポートします。
  • 自動プロパティをサポートします。
  • XML読み取りおよび書き込みメソッドを生成します(シリアライズ/デシリアライズ)。
  • データバインディングのサポート(WPF、Xamarin)。
  • WCF(DataMember属性)。
  • XMLエンコーディングのサポート(UTF-8 / 32、ASCII、Unicode、カスタム)。
  • キャメルケース/パスカルケース対応。
  • 制限のサポート([StringLengthAttribute = true / false]、[RegularExpressionAttribute = true / false]、[RangeAttribute = true / false])。
  • 大きく複雑なXSDファイルをサポートします。
  • DotNet Coreと標準のサポート

0

私はこの質問が古いことを知っていますが、私はそれに出くわしました、そして私は、まあ、他の皆とは異なる答えを持っています:-)

通常の方法(上記のコメンターによる)は、クラスを生成してxmlを非直列化することです。

しかし、(警告:ここでは恥知らずな自己宣伝)私はここで、あなたが必要としないnugetパッケージを公開しました。あなたはただ行く:

string xml = System.IO.File.ReadAllText(@"C:\test\books.xml");
var book = Dandraka.XmlUtilities.XmlSlurper.ParseText(xml);

それは文字通りそれだけで、他には何も必要ありません。そして、最も重要なのは、xmlが変更されると、オブジェクトも自動的に変更されることです。

dllを直接ダウンロードする場合は、githubページがこちらにあります


-7
public string Serialize<T>(T settings)
{
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    StringWriter outStream = new StringWriter();
    serializer.Serialize(outStream, settings);
    return outStream.ToString();
}

5
これはシリアル化の方法であり、逆シリアル化の方法ではありません。
alexc95

1
ここにコードを書いたところです。説明がなければ、それは多くの人にとって無意味です。
M.Haché2016

コードがストリームを
破棄
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.