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.