programing

XML 문자열을 개체로 변환

css3 2023. 10. 27. 22:04

XML 문자열을 개체로 변환

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

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

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

이것이 어떻게 행해지는가?

당신은 사용해야 합니다.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);

또는 문자열 판독기를 사용합니다.

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

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

방법 1. XSD 도구


Suppose that you have your XML file in this location C:\path\to\xml\file.xml

  1. 개발자 명령 프롬프트 열기
    에서 찾을 수 있습니다.Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools또는 Windows 8(윈도우 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 - 특수 붙여넣기


Required Visual Studio 2012+ with .Net Framework >= 4.5 as project target and 'Windows Communication Foundation' individual component installed

  1. XML 파일의 내용을 클립보드로 복사
  2. 새로운 빈 클래스 파일(++)ShiftAltC을 솔루션에 추가합니다.
  3. 해당 파일을 열고 메뉴 클릭Edit > Paste special > Paste XML As Classes
    enter image description here

그것으로 끝!

사용.


이 도우미 클래스에서는 사용 방법이 매우 간단합니다.

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

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

관리자로서 Visual Studio 2013을 간단히 실행...XML 파일의 내용을 복사합니다.Visual Studio 2013 > Edit > Paste Special > Paste Xml을 C# Classes로 붙여넣기 Xml 파일 내용에 따라 C# 클래스를 만듭니다.

누군가 이것이 유용하다고 생각할 경우를 대비해:

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

위에서 설명한 대로 클래스를 생성하거나 수동으로 작성할 수 있습니다.

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

그런 다음 ExtendedXml Serializer를 사용하여 직렬화 및 역직렬화할 수 있습니다.

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

이 직렬화기는 다음을 지원합니다.

  • 표준 XML Serializer의 deserialization xml
  • 직렬화 클래스, 구조, 일반 클래스, 프리미티브 유형, 일반 목록 및 사전, 배열, 열거
  • 속성 인터페이스가 있는 직렬화 클래스
  • 직렬화 순환 참조 및 참조 ID
  • 이전 버전의 xml의 역직렬화
  • 속성 암호화
  • 사용자 지정 직렬화기
  • XmlElement 특성 및 XmlRoot 특성 지원
  • POCO - 모든 구성(마이그레이션, 사용자 지정 직렬화기...)이 클래스 외부에 있습니다.

확장 XmlSerializer 지원.NET 4.5 이상 및 .NET Core.WebApi 및 AspCore와 통합할 수 있습니다.

xsd를 사용할 수 있습니다.에서 스키마 바인딩된 클래스를 생성합니다.그런 다음 XmlSerializer를 사용하여 문자열을 역직렬화합니다. http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.deserialize.aspx

데미안의 훌륭한 대답을 단순화하면,

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

저는 현재(2020-07-24)와 같이 모든 답변을 살펴보았는데, 이 문제를 해결하기 위해서는 좀 더 친숙한 방법이 있어야 하는데, 그것은 다음과 같습니다.

두가지 시나리오...하나는 XML 문자열이 잘 형성되어 있는 경우입니다. 즉, 다음과 같은 것으로 시작합니다.<?xml version="1.0" encoding="utf-16"?>또는 그것의 좋아요들은, 뿌리의 요소를 접하기 전에,<msg>문제에 있어서는다른 하나는 잘 형성되지 않은 경우, 즉 루트 요소(예: 루트 요소)일 뿐입니다.<msg>질문에서) 및 해당 자식 노드만 해당합니다.

먼저, 대소문자를 구분하지 않는 이름의 경우 XML에 있는 루트 노드의 자식 노드와 일치하는 속성을 포함하는 단순한 클래스입니다. 그러면, 질문에서 보면 다음과 같습니다.

public class TheModel
{
    public int Id { get; set; }
    public string Action { get; set; }
}

다음은 코드의 나머지 부분입니다.

// These are the key using statements to add.
using Newtonsoft.Json;
using System.Xml;

bool isWellFormed = false;
string xml =  = @"
<msg>
   <id>1</id>
   <action>stop</action>
</msg>
";

var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);
if (isWellFormed)
{
    xmlDocument.RemoveChild(xmlDocument.FirstChild); 
    /* i.e. removing the first node, which is the declaration part. 
    Also, if there are other unwanted parts in the XML, 
    write another similar code to locate the nodes 
    and remove them to only leave the desired root node 
    (and its child nodes).*/
}

var serializedXmlNode = JsonConvert.SerializeXmlNode(
            xmlDocument, 
            Newtonsoft.Json.Formatting.Indented, 
            true
            );
var theDesiredObject = JsonConvert.DeserializeObject<TheModel>(serializedXmlNode);

이 질문이 오래된 질문이라는 것을 알지만, 우연히 발견했고, 다른 모든 사람들과는 다른 대답이 있습니다 :-)

일반적인 방법은 (위의 주석자들이 언급한 것처럼) 클래스를 생성하고 xml을 디시리얼화하는 것입니다.

하지만 (경고: 파렴치한 자기 홍보) 저는 당신이 필요하지 않은, 여기에 nuget package를 출판했습니다.그냥 가봐요.

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

그것은 문자 그대로입니다. 다른 것은 필요 없습니다.그리고 가장 중요한 것은 xml이 변경되면 개체도 자동으로 변경됩니다.

dll을 직접 다운로드하고 싶다면 github 페이지가 여기에 있습니다.

사용자 지정 개체로 DTO 생성

아래 메서드를 사용하여 JAXB를 사용하여 XML String을 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;
}

xml 메시지의 xsd가 있는 경우 를 사용하여 c# 클래스를 생성할 수 있습니다.넷 xsd.exe 도구

그런 다음 이 .Net 클래스를 사용하여 xml을 생성할 수 있습니다.

여기에 있는 다른 답변 외에도 XmlDocument 클래스를 사용하여 XML DOM과 유사한 읽기를 수행하거나 XmlReader, 빠른 순방향 전용 읽기기를 사용하여 "손으로" 수행할 수 있습니다.

Advanced xsd to c# classs 생성 도구를 사용하는 또 다른 방법 : xsd2code.com .이 도구는 매우 편리하고 강력합니다.xsd보다 커스터마이징이 훨씬 더 많습니다.Visual Studio의 exe 도구.Xsd2Code++는 목록 또는 배열을 사용하도록 사용자 지정할 수 있으며 Import 문이 많은 대규모 스키마를 지원합니다.

일부 기능에 대한 참고,

  • XSD 스키마 또는 XML 파일에서 유연한 C# 또는 Visual Basic 코드로 비즈니스 개체를 생성합니다.
  • 지원 프레임워크 2.0 ~ 4.x
  • 강력한 유형의 컬렉션(List, Observable Collection, MyCustom Collection)을 지원합니다.
  • 자동 속성을 지원합니다.
  • XML 읽기 및 쓰기 메서드를 생성합니다(직렬화/직렬화).
  • 데이터 바인딩 지원(WPF, Xamarin).
  • WCF(DataMember 속성).
  • XML 인코딩 지원(UTF-8/32, ASCII, Unicode, Custom).
  • 카멜 케이스 / 파스칼 케이스 지원.
  • 제한 지원([StringLengthAttribute=true/false], [Regular ExpressionAttribute=true/false], [RangeAttribute=true/false]).
  • 크고 복잡한 XSD 파일을 지원합니다.
  • DotNet Core 및 표준 지원
public string Serialize<T>(T settings)
{
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    StringWriter outStream = new StringWriter();
    serializer.Serialize(outStream, settings);
    return outStream.ToString();
}

언급URL : https://stackoverflow.com/questions/3187444/convert-xml-string-to-object