XML स्ट्रिंग को ऑब्जेक्ट में कनवर्ट करें


179

मैं एक सॉकेट पर XML तार प्राप्त कर रहा हूं, और इन्हें C # ऑब्जेक्ट में परिवर्तित करना चाहूंगा।

संदेश फॉर्म के हैं:

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

मैं। नेट के लिए नया हूं, और मुझे यह प्रदर्शन करने के लिए सबसे अच्छा अभ्यास नहीं है। मैंने पहले जावा के लिए JAXB का उपयोग किया है, और यह निश्चित नहीं था कि क्या ऐसा ही कुछ है, या यदि यह एक अलग तरह से संभाला जाएगा।


3
क्या आपके पास ऐसी वस्तुएं हैं जो आप बन गए हैं या आप वस्तुओं को गतिशील रूप से उत्पन्न करना चाहते हैं?
स्टीफन

इस पोस्ट को देखें: http://stackoverflow.com/questions/765422/jaxb-equivalent-in-c
Aykut ikevik

मेरे लिए यह सबसे अच्छा विकल्प था: stackoverflow.com/a/24184283/2647430
इवान लोपेज़

जवाबों:


277

आपको उस xsd.exeउपकरण का उपयोग करने की आवश्यकता है जो विंडोज एसडीके के साथ एक निर्देशिका में कुछ इसी तरह स्थापित होता है:

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

और 64-बिट कंप्यूटरों पर:

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

और विंडोज 10 कंप्यूटर पर:

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

पहले रन पर, आप उपयोग करते हैं xsd.exeऔर आप अपने नमूने XML को XSD फ़ाइल (XML स्कीमा फ़ाइल) में परिवर्तित करते हैं:

xsd yourfile.xml

यह आपको देता है yourfile.xsd, जो एक दूसरे चरण में, आप फिर से xsd.exeC # वर्ग में उपयोग करके परिवर्तित कर सकते हैं :

xsd yourfile.xsd /c

इससे आपको एक ऐसी फ़ाइल मिलनी चाहिए yourfile.csजिसमें एक C # क्लास होगी जिसका उपयोग आप XML फ़ाइल को प्राप्त करने के लिए कर सकते हैं - जो कुछ इस प्रकार है:

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

या एक स्ट्रिंगर का उपयोग करें:

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

विस्तृत विवरण के लिए धन्यवाद। मेरे मामले में, XML एक सॉकेट पर आ रहा है, और एक स्ट्रिंग है। मैं XML फ़ाइल के बजाय स्ट्रिंग को डी-सीरियल कैसे करूंगा?
स्टीव

5
@ साइट: आप एक StringReader खोल सकते हैं और Deserialize विधि पास कर सकते हैं। StringReader TextReader से निकलता है।
Skurmedel

क्या आप Linq का उपयोग करके उल्लिखित एक Fahad के लिए अपने दृष्टिकोण को पसंद करेंगे?
स्टीव

2
@Steve: हाँ, मैं करूँगा - एक वस्तु में deserializing और ऑब्जेक्ट के गुणों पर प्रहार करने में सक्षम होने के नाते XML तत्वों, विशेषताओं, चाइल्ड नोड्स आदि के साथ बहुत सारे झगड़े करने की तुलना में आसान लगता है। Linq-to-XML महान है अगर एक्सएमएल अनियमित है और हर समय बदलता है, या समय से पहले नहीं जाना जाता है।
marc_s

7
यह वेब साइट xsd टूल IMO से बहुत आसान है: xmltocsharp.azurewebooks.net
nasch

226

आपके पास दो संभावनाएँ हैं।

विधि 1. XSD उपकरण


मान लीजिए कि आपके पास अपनी XML फ़ाइल इस स्थान पर है C:\path\to\xml\file.xml

  1. ओपन डेवलपर कमांड प्रॉम्प्ट
    आप इसे पा सकते हैं Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools या अगर आपके पास विंडोज 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 - विशेष पेस्ट करें


आवश्यक Visual Studio 2012+ के साथ .Net फ्रेमवर्क> = 4.5 परियोजना लक्ष्य के रूप में और 'विंडोज कम्युनिकेशन फाउंडेशन' व्यक्तिगत घटक स्थापित

  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
खुश होती है। पुन: विधि 2, आपको लक्ष्य .net 4.5 और विकल्प उपलब्ध नहीं है।
टिंबर 33

12
विधि 2 हास्यास्पद रूप से उपयोगी है! उसके लिए धन्यवाद। मुझे पता नहीं था कि अस्तित्व में है।
डोमिनिक बिंदली

1
विधि 2 के लिए यश, एक आकर्षण की तरह काम करता है। बोरिंग कक्षाओं को लागू करने के बिना बस एक XML प्रोग्राम को पार्स करने की कोशिश करने पर महान।
एलेक्स

1
आपको पहली विधि के रूप में "पेस्ट स्पेशल" बनाना चाहिए - यह सबसे सरल है। 2017 में सीमा "। नेट फ्रेमवर्क> = 4.5" महत्वपूर्ण नहीं है।
माइकल फ्रीजिम

2
"एक्सएमएल को कक्षाओं के रूप में चिपकाएं" विजुअल स्टूडियो के लिए डब्ल्यूसीएफ कार्यभार स्थापित करने की आवश्यकता है।
लेननर्ट

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 = ''> अपेक्षित नहीं था। "}, किसी भी विचार?
प्रशांत

समस्या यह है, आपको अपनी कक्षा को पूरी तरह से अग्रिम रूप से गठित करने की आवश्यकता है। शायद एक फ़ंक्शन जो एक्सएमएल दिए जाने पर एक वर्ग को आउटपुट करता है? xsd.exe हिट और मिस (ज्यादातर जटिल सामान के लिए याद आती है) ...
Yumi Koizumi

1
ओह माई गॉड मैंने घंटों .nets xml धारावाहिक के साथ काम किया, और यह गेट के ठीक बाहर काम किया।
क्रिस्टोफर क्लार्क

11

बस अपने विज़ुअल स्टूडियो 2013 को व्यवस्थापन के रूप में चलाएं ... अपनी Xml फ़ाइल की सामग्री को कॉपी करें .. विज़ुअल स्टूडियो 2013 पर जाएं> संपादित करें> विशेष # चिपकाएँ Xml को C # क्लासेस के रूप में पेस्ट करें यह आपकी Xml फ़ाइल सामग्री के अनुसार आपकी सी # कक्षाएं बनाएगा।


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; }
}

तो फिर आप serialize और deserialize करने के लिए ExtendedXmlSerializer का उपयोग कर सकते हैं ।

instalation आप से ExtendedXmlSerializer स्थापित कर सकते हैं nuget या निम्नलिखित कमांड चलाएँ:

Install-Package ExtendedXmlSerializer

क्रमबद्धता:

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

deserialization

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

इस धारावाहिक का समर्थन:

  • मानक XMLSerializer से Deserialization xml
  • सीरियलाइज़ेशन वर्ग, संरचना, सामान्य वर्ग, आदिम प्रकार, सामान्य सूची और शब्दकोश, सरणी, एनम
  • संपत्ति इंटरफ़ेस के साथ सीरियल क्लास
  • क्रमिकरण परिपत्र संदर्भ और संदर्भ आईडी
  • Xml के पुराने संस्करण का वर्णन
  • संपत्ति एन्क्रिप्शन
  • कस्टम धारावाहिक
  • समर्थन XmlElementAttribute और XmlRootAttribute
  • POCO - सभी कॉन्फ़िगरेशन (माइग्रेशन, कस्टम क्रमिक ...) वर्ग के बाहर हैं

ExtendedXmlSerializer .NET 4.5 या उच्चतर और .NET कोर का समर्थन करता है । आप इसे 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

CustomObject के रूप में एक DTO बनाएँ

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

अन्य उत्तर के अलावा यहां आप स्वाभाविक रूप से उपयोग कर सकते हैं XmlDocument वर्ग, के लिए XML डोम की तरह पढ़ना, या XmlReader , तेजी से आगे-केवल पाठक, यह "हाथ से" क्या करना है।


0

एक उन्नत xsd के साथ c # क्लासेस जनरेशन टूल्स का दूसरा तरीका: xsd2code.com। यह उपकरण बहुत काम और शक्तिशाली है। यह Visual Studio से xsd.exe उपकरण की तुलना में बहुत अधिक अनुकूलन है। Xsd2Code ++ को सूचियों या ऐरे का उपयोग करने के लिए अनुकूलित किया जा सकता है और आयात विवरणों के साथ बड़े स्कीमाओं का समर्थन करता है।

कुछ विशेषताओं का नोट,

  • XSD स्कीमा या XML फ़ाइल से लचीली C # या विज़ुअल बेसिक कोड से व्यावसायिक ऑब्जेक्ट्स बनाता है।
  • सपोर्ट फ्रेमवर्क 2.0 से 4.x
  • मजबूत टाइप किए गए संग्रह का समर्थन करें (सूची, ओब्जर्वेबल कॉलेलेक्शन, माईक्रूटलकॉलेक्शन)।
  • स्वचालित गुणों का समर्थन करें।
  • XML पढ़ने और लिखने के तरीके (क्रमांकन / deserialization) उत्पन्न करें।
  • डेटाबाइंडिंग सपोर्ट (WPF, Xamarin)।
  • WCF (DataMember विशेषता)।
  • XML एन्कोडिंग समर्थन (UTF-8/32, ASCII, यूनिकोड, कस्टम)।
  • ऊँट केस / पास्कल केस समर्थन।
  • प्रतिबंध का समर्थन ([StringLengthAttribute = true / false], [RegularExpressionAttribute = true / false], [RangeAttribute = true / false])।
  • बड़ी और जटिल XSD फ़ाइल का समर्थन करें।
  • डॉटनेट कोर और मानक का समर्थन

0

मुझे पता है कि यह सवाल पुराना है, लेकिन मैं इसमें लड़खड़ा गया और मेरे पास एक अलग जवाब है, ठीक है, बाकी सब :-)

सामान्य तरीका (टिप्पणीकारों के रूप में ऊपर उल्लेख किया गया है) एक वर्ग उत्पन्न करना है और अपने xml को क्रमबद्ध करना है।

लेकिन ( चेतावनी: बेशर्म आत्म-प्रचार यहाँ ) मैंने अभी एक नगेट पैकेज प्रकाशित किया है, यहाँ , जिसके साथ आपको नहीं करना है। तुम बस जाओ:

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
आपने यहाँ कोड लिखा है। बिना किसी स्पष्टीकरण के, यह कई लोगों के लिए अर्थहीन है।
एम। हैच

कोड धाराओं का निपटान नहीं करता है
बिगफुट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.