XML 문자열을 객체로 변환


179

소켓을 통해 XML 문자열을 받고 있는데 이것을 C # 객체로 변환하고 싶습니다.

메시지는 다음과 같은 형식입니다.

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

.Net을 처음 사용하고 있으며이를 수행하는 가장 좋은 방법은 확실하지 않습니다. 이전에 Java 용 JAXB를 사용해 왔으며 비슷한 것이 있는지 또는 다른 방식으로 처리되는지 확실하지 않았습니다.


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두 번째 단계에서 xsd.exeC # 클래스 로 다시 변환 할 수 있습니다 .

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를 사용하여 언급 한 Fahad에 대한 접근 방식을 선호하십니까?
Steve

2
@Steve : 예, 객체를 직렬화 해제하고 객체의 속성을 찌를 수있는 것은 XML 요소, 속성, 자식 노드 등을 많이 사용하는 것보다 훨씬 쉽습니다. Linq-to-XML은 XML은 불규칙하며 항상 변경되거나 미리 알려지지 않습니다.
marc_s

7
이 웹 사이트는 xsd 도구 IMO보다 훨씬 쉽습니다. xmltocsharp.azurewebsites.net
nasch

226

두 가지 가능성이 있습니다.

방법 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 및 'Windows Communication Foundation'개별 구성 요소가 설치된 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>();

7
건배. re : 방법 2, .net 4.5를 대상으로 지정해야합니다. 그렇지 않으면 옵션을 사용할 수 없습니다.
timB33

12
방법 2는 엄청나게 유용합니다! 고마워 나는 존재하지 않았다.
Dominic Bindley

1
방법 2에 대한 명성은 매력처럼 작동합니다. 지루한 클래스를 구현하지 않고도 프로그래밍 방식으로 XML을 단순히 구문 분석하려고 할 때 좋습니다.
Alex

1
"붙여 넣기"를 첫 번째 방법으로 만들어야합니다. 가장 간단한 방법입니다. 제한 ".Net Framework> = 4.5"는 2017 년에 중요하지 않습니다.
Michael Freidgeim

2
"클래스로 XML 붙여 넣기"에는 Visual Studio 용 WCF 워크로드가 설치되어 있어야합니다.
Lennart

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 is hit & miss (주로 복잡한 것들이 그리워요) ...
Yumi Koizumi

1
오 세상에 나는 .nets xml serializer를 처리하는 데 몇 시간을 보냈으며, 이것은 게이트에서 바로 작동했습니다.
christopher clark

11

관리로 Visual Studio 2013을 실행하기 만하면됩니다 ... Xml 파일의 내용을 복사하십시오. Visual Studio 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 를 사용 하여 직렬화 및 역 직렬화를 수행 할 수 있습니다 .

설치 nuget 에서 ExtendedXmlSerializer를 설치 하거나 다음 명령을 실행할 수 있습니다 .

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

Damian의 훌륭한 답변을 단순화합니다.

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

다른 답변 외에도 여기 에서 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, Custom).
  • 낙타 케이스 / 파스칼 케이스 지원.
  • 제한 지원 ([StringLengthAttribute = true / false], [RegularExpressionAttribute = true / false], [RangeAttribute = true / false]).
  • 크고 복잡한 XSD 파일을 지원합니다.
  • DotNet Core 및 표준 지원

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
여기에 코드를 작성했습니다. 설명이 없으면 많은 사람들에게 의미가 없습니다.
M. Haché

코드는 스트림을 처리하지 않습니다
bigfoot
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.