prosource

XML 문서를 병렬화하는 방법

probook 2023. 10. 20. 13:50
반응형

XML 문서를 병렬화하는 방법

XML 문서를 역직렬화하려면 어떻게 해야 합니까?

<?xml version="1.0" encoding="utf-8"?>
<Cars>
  <Car>
    <StockNumber>1020</StockNumber>
    <Make>Nissan</Make>
    <Model>Sentra</Model>
  </Car>
  <Car>
    <StockNumber>1010</StockNumber>
    <Make>Toyota</Make>
    <Model>Corolla</Model>
  </Car>
  <Car>
    <StockNumber>1111</StockNumber>
    <Make>Honda</Make>
    <Model>Accord</Model>
  </Car>
</Cars>

나는 이것을 가지고 있습니다.

[Serializable()]
public class Car
{
    [System.Xml.Serialization.XmlElementAttribute("StockNumber")]
    public string StockNumber{ get; set; }

    [System.Xml.Serialization.XmlElementAttribute("Make")]
    public string Make{ get; set; }

    [System.Xml.Serialization.XmlElementAttribute("Model")]
    public string Model{ get; set; }
}

.

[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
    [XmlArrayItem(typeof(Car))]
    public Car[] Car { get; set; }

}

.

public class CarSerializer
{
    public Cars Deserialize()
    {
        Cars[] cars = null;
        string path = HttpContext.Current.ApplicationInstance.Server.MapPath("~/App_Data/") + "cars.xml";

        XmlSerializer serializer = new XmlSerializer(typeof(Cars[]));

        StreamReader reader = new StreamReader(path);
        reader.ReadToEnd();
        cars = (Cars[])serializer.Deserialize(reader);
        reader.Close();

        return cars;
    }
}

안 되는 것 같네요 :-(

xml을 파일에 저장하고 xsd를 사용하여 C# 클래스를 생성하는 것은 어떻습니까?

  1. 파일을 디스크에 씁니다(foo.xml로 이름 지었습니다).
  2. xsd 생성:xsd foo.xml
  3. C# 생성:xsd foo.xsd /classes

Etvoila - 및 C# 코드 파일을 통해 데이터를 읽을 수 있어야 합니다.XmlSerializer:

    XmlSerializer ser = new XmlSerializer(typeof(Cars));
    Cars cars;
    using (XmlReader reader = XmlReader.Create(path))
    {
        cars = (Cars) ser.Deserialize(reader);
    }

(프로젝트에서 생성된 foo.cs include)

여기 작동 중인 버전이 있습니다.제가 바꿨습니다.XmlElementAttribute에의 레이블.XmlElementxml에서 StockNumber, Make 및 Model 값은 속성이 아닌 요소이기 때문입니다.그리고 나는 그것을 제거했습니다.reader.ReadToEnd();(이 함수는 전체 스트림을 읽고 문자열을 반환하므로,Deserialize()기능이 더 이상 리더를 사용할 수 없습니다.위치는 시냇물의 끝에 있었습니다.).이름을 짓는 것도 몇 가지 자유로웠습니다 :).

클래스는 다음과 같습니다.

[Serializable()]
public class Car
{
    [System.Xml.Serialization.XmlElement("StockNumber")]
    public string StockNumber { get; set; }

    [System.Xml.Serialization.XmlElement("Make")]
    public string Make { get; set; }

    [System.Xml.Serialization.XmlElement("Model")]
    public string Model { get; set; }
}


[Serializable()]
[System.Xml.Serialization.XmlRoot("CarCollection")]
public class CarCollection
{
    [XmlArray("Cars")]
    [XmlArrayItem("Car", typeof(Car))]
    public Car[] Car { get; set; }
}

병렬화 함수:

CarCollection cars = null;
string path = "cars.xml";

XmlSerializer serializer = new XmlSerializer(typeof(CarCollection));

StreamReader reader = new StreamReader(path);
cars = (CarCollection)serializer.Deserialize(reader);
reader.Close();

그리고 약간 수정된 xml(<Cars>를 랩할 새 요소를 추가해야 했습니다.)Net은 어레이의 병렬화에 까다롭습니다.):

<?xml version="1.0" encoding="utf-8"?>
<CarCollection>
<Cars>
  <Car>
    <StockNumber>1020</StockNumber>
    <Make>Nissan</Make>
    <Model>Sentra</Model>
  </Car>
  <Car>
    <StockNumber>1010</StockNumber>
    <Make>Toyota</Make>
    <Model>Corolla</Model>
  </Car>
  <Car>
    <StockNumber>1111</StockNumber>
    <Make>Honda</Make>
    <Model>Accord</Model>
  </Car>
</Cars>
</CarCollection>

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

방법 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+

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

다음 토막글은 다음과 같은 방법을 사용해야 하며 대부분의 직렬화 속성은 무시할 수 있습니다.

public class Car
{
  public string StockNumber { get; set; }
  public string Make { get; set; }
  public string Model { get; set; }
}

[XmlRootAttribute("Cars")]
public class CarCollection
{
  [XmlElement("Car")]
  public Car[] Cars { get; set; }
}

...

using (TextReader reader = new StreamReader(path))
{
  XmlSerializer serializer = new XmlSerializer(typeof(CarCollection));
  return (CarCollection) serializer.Deserialize(reader);
}

도움이 되는지 확인:

[Serializable()]
[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
    [XmlArrayItem(typeof(Car))]
    public Car[] Car { get; set; }
}

.

[Serializable()]
public class Car
{
    [System.Xml.Serialization.XmlElement()]
    public string StockNumber{ get; set; }

    [System.Xml.Serialization.XmlElement()]
    public string Make{ get; set; }

    [System.Xml.Serialization.XmlElement()]
    public string Model{ get; set; }
}

그리고 xsd를 사용하지 못하는 것.visual studio와 함께 제공되는 exe 프로그램은 해당 xml 파일을 기반으로 스키마 문서를 생성한 후, 이를 다시 사용하여 스키마 문서를 기반으로 클래스를 생성합니다.

나는 .net이 '배열을 병렬화하는 것에 까다롭다'고 생각하지 않습니다.첫 번째 xml 문서의 형식이 좋지 않습니다.뿌리가 있는 것처럼 보이지만 뿌리 요소는 없습니다.표준 xml 문서에는 루트와 최소 1개의 요소(있는 경우)가 있습니다.예에서:

<Root> <-- well, the root
  <Cars> <-- an element (not a root), it being an array
    <Car> <-- an element, it being an array item
    ...
    </Car>
  </Cars>
</Root>

초보자용

저는 여기서의 답변이 매우 도움이 된다는 것을 알게 되었고, 이는 제가 아직도 이 일을 해결하는 데 어려움을 겪고 있다는 것을 의미합니다.그래서 누군가에게 도움이 될 경우에는 제가 해결책을 설명해 드리겠습니다.

원래 질문의 XML입니다.은 xml은 Class1.xml.path이 파일은 이 xml 파일을 찾기 위해 코드에 사용됩니다.

저는 @erymski의 답변을 이용해 이것을 작동시켰습니다. 그래서 Car.cs 라는 파일을 만들고 다음을 추가했습니다.

using System.Xml.Serialization;  // Added

public class Car
{
    public string StockNumber { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
}

[XmlRootAttribute("Cars")]
public class CarCollection
{
    [XmlElement("Car")]
    public Car[] Cars { get; set; }
}

@erymski가 제공하는 다른 비트의 코드는...

using (TextReader reader = new StreamReader(path))
{
  XmlSerializer serializer = new XmlSerializer(typeof(CarCollection));
  return (CarCollection) serializer.Deserialize(reader);
}

( )에 메인 프로그램(Program.cs )에 들어갑니다.static CarCollection XCar()다음과 같이:

using System;
using System.IO;
using System.Xml.Serialization;

namespace ConsoleApp2
{
    class Program
    {

        public static void Main()
        {
            var c = new CarCollection();

            c = XCar();

            foreach (var k in c.Cars)
            {
                Console.WriteLine(k.Make + " " + k.Model + " " + k.StockNumber);
            }
            c = null;
            Console.ReadLine();

        }
        static CarCollection XCar()
        {
            using (TextReader reader = new StreamReader(@"C:\Users\SlowLearner\source\repos\ConsoleApp2\ConsoleApp2\Class1.xml"))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(CarCollection));
                return (CarCollection)serializer.Deserialize(reader);
            }
        }
    }
}

도움이 되길 바라요 :-)

만약 당신의 .xml 파일이 디스크의 어딘가에서 생성되었다면 그리고 당신이 사용했다면 이 코드 블록을 시도해보세요.List<T>:

//deserialization

XmlSerializer xmlser = new XmlSerializer(typeof(List<Item>));
StreamReader srdr = new StreamReader(@"C:\serialize.xml");
List<Item> p = (List<Item>)xmlser.Deserialize(srdr);
srdr.Close();`

:C:\serialize.xml 파일의xml 파일의 경로입니다.필요에 따라 변경할 수 있습니다.

Kevin의 답변은, 실제 환경에서는 자신의 요구에 맞게 원래 XML을 변경할 수 없는 경우가 많다는 사실 외에도 좋습니다.

원본 XML에 대한 간단한 솔루션도 있습니다.

[XmlRoot("Cars")]
public class XmlData
{
    [XmlElement("Car")]
    public List<Car> Cars{ get; set; }
}

public class Car
{
    public string StockNumber { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
}

그러면 다음과 같은 전화를 걸 수 있습니다.

var ser = new XmlSerializer(typeof(XmlData));
var data = (XmlData)ser.Deserialize(XmlReader.Create(PathToCarsXml));

라이너 하나:

var object = (Cars)new XmlSerializer(typeof(Cars)).Deserialize(new StringReader(xmlString));

Xml 직렬화 및 병렬화를 위해 이 일반 클래스를 사용해 보십시오.

public class SerializeConfig<T> where T : class
{
    public static void Serialize(string path, T type)
    {
        var serializer = new XmlSerializer(type.GetType());
        using (var writer = new FileStream(path, FileMode.Create))
        {
            serializer.Serialize(writer, type);
        }
    }

    public static T DeSerialize(string path)
    {
        T type;
        var serializer = new XmlSerializer(typeof(T));
        using (var reader = XmlReader.Create(path))
        {
            type = serializer.Deserialize(reader) as T;
        }
        return type;
    }
}

XML 문서를 역직렬화하는 일반 클래스는 어떻습니까?

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Generic class to load any xml into a class
// used like this ...
// YourClassTypeHere InfoList = LoadXMLFileIntoClass<YourClassTypeHere>(xmlFile);

using System.IO;
using System.Xml.Serialization;

public static T LoadXMLFileIntoClass<T>(string xmlFile)
{
    T returnThis;
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    if (!FileAndIO.FileExists(xmlFile))
    {
        Console.WriteLine("FileDoesNotExistError {0}", xmlFile);
    }
    returnThis = (T)serializer.Deserialize(new StreamReader(xmlFile));
    return (T)returnThis;
}

이 부분은 필요하지 않을 수도 있고 필요하지 않을 수도 있습니다.Visual Studio에서 XML 문서를 열고 XML을 마우스 오른쪽 단추로 클릭한 후 속성을 선택합니다.그런 다음 스키마 파일을 선택합니다.

아이디어는 역직렬화를 위해 모든 레벨을 처리하는 것입니다. 유사한 문제를 해결한 샘플 솔루션을 참조하십시오.

<?xml version="1.0" ?> 
 <TRANSACTION_RESPONSE>
    <TRANSACTION>
        <TRANSACTION_ID>25429</TRANSACTION_ID> 
        <MERCHANT_ACC_NO>02700701354375000964</MERCHANT_ACC_NO> 
        <TXN_STATUS>F</TXN_STATUS> 
        <TXN_SIGNATURE>a16af68d4c3e2280e44bd7c2c23f2af6cb1f0e5a28c266ea741608e72b1a5e4224da5b975909cc43c53b6c0f7f1bbf0820269caa3e350dd1812484edc499b279</TXN_SIGNATURE> 
        <TXN_SIGNATURE2>B1684258EA112C8B5BA51F73CDA9864D1BB98E04F5A78B67A3E539BEF96CCF4D16CFF6B9E04818B50E855E0783BB075309D112CA596BDC49F9738C4BF3AA1FB4</TXN_SIGNATURE2> 
        <TRAN_DATE>29-09-2015 07:36:59</TRAN_DATE> 
        <MERCHANT_TRANID>150929093703RUDZMX4</MERCHANT_TRANID> 
        <RESPONSE_CODE>9967</RESPONSE_CODE> 
        <RESPONSE_DESC>Bank rejected transaction!</RESPONSE_DESC> 
        <CUSTOMER_ID>RUDZMX</CUSTOMER_ID> 
        <AUTH_ID /> 
        <AUTH_DATE /> 
        <CAPTURE_DATE /> 
        <SALES_DATE /> 
        <VOID_REV_DATE /> 
        <REFUND_DATE /> 
        <REFUND_AMOUNT>0.00</REFUND_AMOUNT> 
    </TRANSACTION>
  </TRANSACTION_RESPONSE> 

위 XML은 두 가지 레벨로 처리됩니다.

  [XmlType("TRANSACTION_RESPONSE")]
public class TransactionResponse
{
    [XmlElement("TRANSACTION")]
    public BankQueryResponse Response { get; set; }

}

내부 레벨

public class BankQueryResponse
{
    [XmlElement("TRANSACTION_ID")]
    public string TransactionId { get; set; }

    [XmlElement("MERCHANT_ACC_NO")]
    public string MerchantAccNo { get; set; }

    [XmlElement("TXN_SIGNATURE")]
    public string TxnSignature { get; set; }

    [XmlElement("TRAN_DATE")]
    public DateTime TranDate { get; set; }

    [XmlElement("TXN_STATUS")]
    public string TxnStatus { get; set; }


    [XmlElement("REFUND_DATE")]
    public DateTime RefundDate { get; set; }

    [XmlElement("RESPONSE_CODE")]
    public string ResponseCode { get; set; }


    [XmlElement("RESPONSE_DESC")]
    public string ResponseDesc { get; set; }

    [XmlAttribute("MERCHANT_TRANID")]
    public string MerchantTranId { get; set; }

}

여러 레벨을 필요로 하는 동일한 방법car as array 다단계 역직렬화의 경우 이 예를 확인합니다.

xsd를 사용하여 오류가 발생하는 경우.xsd 파일을 만들려면 msdn에 언급된 XmlSchemaInference 클래스를 사용합니다.다음은 유닛 테스트를 통해 입증할 수 있습니다.

using System.Xml;
using System.Xml.Schema;

[TestMethod]
public void GenerateXsdFromXmlTest()
{
    string folder = @"C:\mydir\mydata\xmlToCSharp";
    XmlReader reader = XmlReader.Create(folder + "\some_xml.xml");
    XmlSchemaSet schemaSet = new XmlSchemaSet();
    XmlSchemaInference schema = new XmlSchemaInference();

    schemaSet = schema.InferSchema(reader);


    foreach (XmlSchema s in schemaSet.Schemas())
    {
        XmlWriter xsdFile = new XmlTextWriter(folder + "\some_xsd.xsd", System.Text.Encoding.UTF8);
        s.Write(xsdFile);
        xsdFile.Close();
    }
}

// now from the visual studio command line type: xsd some_xsd.xsd /classes

자동차 속성을 XmlArrayItem에서 XmlElment로 하나의 속성만 변경하면 됩니다.즉, 부터

[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
    [XmlArrayItem(typeof(Car))]
    public Car[] Car { get; set; }
}

로.

[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
    [XmlElement("Car")]
    public Car[] Car { get; set; }
}

내 솔루션:

  1. 사용하다Edit > Past Special > Paste XML As Classes코드로 수업을 받다
  2. 이 클래스의 목록을 만들어 보십시오. 해당 클래스의 목록을 만듭니다.List<class1>), 다음을 사용합니다.XmlSerializer그 목록을 a로 연속해서 작성하는군요xml일.
  3. 이제 당신은 그 파일의 본문을 당신의 데이터로 대체하고 당신은deserialize그것.

코드:

StreamReader sr = new StreamReader(@"C:\Users\duongngh\Desktop\Newfolder\abc.txt");
XmlSerializer xml = new XmlSerializer(typeof(Class1[]));
var a = xml.Deserialize(sr);
sr.Close();

참고: 루트 이름을 주의해야 합니다. 변경하지 마십시오.저는 "ArrayOfClass1"입니다.

언급URL : https://stackoverflow.com/questions/364253/how-to-deserialize-xml-document

반응형