วิธีการดีซีเรียลไลซ์เอกสาร XML


472

ฉันจะทำการ Deserialize เอกสาร 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;
    }
}

ที่ดูเหมือนจะไม่ทำงาน :-(


ฉันคิดว่าคุณต้องหลบหนีจากวงเล็บมุมในเอกสารตัวอย่างของคุณ
harpo

4
คำตอบนี้ดีจริงๆ: stackoverflow.com/a/19613934/196210
Revious

คำตอบ:


359

นี่คือรุ่นที่ใช้งานได้ ฉันเปลี่ยนXmlElementAttributeป้ายกำกับเป็นXmlElementเพราะในค่า xml ค่า StockNumber, Make and 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; }
}

ฟังก์ชัน Deserialize:

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> ... สุทธิเป็นเรื่องเกี่ยวกับอาร์เรย์ที่ดีซีเรียลไลซ์):

<?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>

68
[Serializable]ซ้ำซ้อนถ้าใช้XmlSerializer; XmlSerializerเพียงแค่ไม่เคยตรวจสอบสิ่งนั้น [Xml...]คุณลักษณะส่วนใหญ่มีความซ้ำซ้อนเนื่องจากเป็นการเลียนแบบพฤติกรรมเริ่มต้น เช่นโดยค่าเริ่มต้นคุณสมบัติที่เรียกว่าStockNumberถูกเก็บไว้เป็นองค์ประกอบชื่อ<StockNumber>- ไม่จำเป็นต้องมีคุณสมบัติสำหรับที่
Marc Gravell

3
โปรดทราบว่า XmlElementAttribute = XmlElement (เป็นคุณสมบัติภาษาที่คุณสามารถละเว้นคำต่อท้าย "แอตทริบิวต์") วิธีแก้ปัญหาจริงที่นี่คือการลบการเรียก ReadToEnd () และการเพิ่มของโหนดรูท แต่ดีกว่าใช้รหัสจาก erymski ซึ่งจะช่วยแก้คำถาม (แยก XML กำหนด)
Flamefire

2
ขอบคุณ Kevin แต่ถ้าฉันลบ CarsCollection ออกจาก XML ตัวอย่าง ฉันลบ Carscollection ออกจากชั้นเรียนและยกเลิกการลงรหัส แต่ไม่ประสบความสำเร็จ
Vikrant

441

วิธีการเกี่ยวกับคุณเพียงแค่บันทึก xml ไปยังไฟล์และใช้xsdเพื่อสร้างคลาส C #?

  1. เขียนไฟล์ลงดิสก์ (ฉันตั้งชื่อมันว่า foo.xml)
  2. สร้าง xsd: xsd foo.xml
  3. สร้าง C #: xsd foo.xsd /classes

Et voila - และไฟล์รหัส C # ที่ควรอ่านข้อมูลผ่านXmlSerializer:

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

(รวม foo.cs ที่สร้างขึ้นในโครงการ)


6
คุณ ... เป็นผู้ชาย! ขอบคุณ สำหรับทุกคนที่ต้องการ "เส้นทาง" สามารถเป็นสตรีมที่คุณสร้างจากการตอบกลับทางเว็บเช่น: var resp = response.Content.ReadAsByteArrayAsync (); var stream = MemoryStream ใหม่ (resp.Result);
Induster

1
ความคิดที่ยอดเยี่ยม แต่ไม่สามารถทำให้ถูกต้องสำหรับรุ่นที่ซับซ้อนกว่าเล็กน้อยของฉันพร้อมแบตเตอรีที่ซ้อนกันหลายชุด ฉันยังคงได้รับข้อผิดพลาดในการแปลงประเภทสำหรับอาร์เรย์ที่ซ้อนกัน - รวมถึงรูปแบบการตั้งชื่อที่สร้างสิ่งที่ต้องการ ดังนั้นฉันจึงไปตามเส้นทางที่กำหนดเอง
GotDibbs

9
ค้นหาเส้นทาง
jwillmer

2
xsd.exe ได้จากพรอมต์คำสั่ง visual studio ไม่ใช่พรอมต์คำสั่งของ windows ดูว่าคุณสามารถเปิดพรอมต์คำสั่งจากภายใน visual studio ภายใต้เครื่องมือ หากไม่ลองเข้าใช้จากโฟลเดอร์ visual studio สำหรับ VS 2012 จะอยู่ที่นี่: C: \ Program Files (x86) \ Microsoft Visual Studio 12.0 \ Common7 \ Tools \ Shortcuts ใน Windows 8 ลองค้นหา "Visual Studio Tools"
goku_da_master

2
สำหรับทุกคนที่กำลังมองหา XSD นี่คือหัวข้อ SO: stackoverflow.com/questions/22975031/ …
SOReader

229

คุณมีความเป็นไปได้สองอย่าง

วิธีที่ 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. สร้างไฟล์ XSDจากไฟล์ xml ของคุณโดยพิมพ์xsd file.xml
  4. สร้างคลาส C #โดยพิมพ์xsd /c file.xsd

และนั่นมัน! คุณได้สร้างคลาส C # จากไฟล์ xml ในC:\path\to\xml\file.cs

วิธีที่ 2 - วางแบบพิเศษ


จำเป็นต้องใช้ 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>();

16
+1 คำตอบที่ดี แต่Paste XML As Classesคำสั่งมีเป้าหมายเพียง. NET 4.5
ravy amiry

1
นี่เป็นวิธีที่ยอดเยี่ยมในการสร้างแบบจำลองหากคุณติดตั้ง vs2012 + ฉันเรียกใช้การล้างข้อมูลรหัส ReSharper อีกครั้งเพื่อใช้คุณสมบัติอัตโนมัติจากนั้นก็จัดเรียงข้อมูลอื่น ๆ ด้วยเช่นกัน คุณสามารถสร้างด้วยวิธีนี้แล้วคัดลอกลงใน proj รุ่นเก่าถ้าจำเป็น
Scotty.NET

4
การกำหนดเป้าหมาย. net4.5 ไม่ใช่ปัญหา เพียงเปิดไฟโครงการชั่วคราวด้วย dotnet4.5 ทำสำเนาของคุณที่นั่นแล้วคัดลอกแหล่งที่มาไปยังโครงการจริงของคุณ
LosManos

2
วัตถุหรือคลาส "แค็ตตาล็อก" อยู่ที่ไหน
CB4

3
สำหรับ "วาง XML เป็นคลาส" เพื่อแสดงในเมนูบนชุมชน VS 2017 คุณต้องติดตั้ง "ASP.NET และการพัฒนาเว็บ" หากไม่มีให้เรียกใช้ตัวติดตั้ง VS อีกครั้งเพื่อแก้ไขการติดตั้งของคุณ
Slion

89

ตัวอย่างต่อไปนี้ควรใช้เคล็ดลับ (และคุณสามารถละเว้นแอตทริบิวต์การทำให้เป็นอันดับส่วนใหญ่ได้):

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

14
นี่เป็นคำตอบเดียวเท่านั้น คำตอบที่ยอมรับมีข้อบกพร่องสองสามข้อที่อาจทำให้ผู้เริ่มต้นสับสน
Flamefire

24

ดูว่าสิ่งนี้จะช่วยให้:

[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.exe ที่มาพร้อมกับ visual studio เพื่อสร้างเอกสาร schema โดยใช้ไฟล์ xml นั้นจากนั้นใช้อีกครั้งเพื่อสร้างคลาสตามเอกสารสกีมา


9

ฉันไม่คิดว่า. net คือ 'การเลือกสรรเกี่ยวกับการดีซีเรียลไลซ์อาร์เรย์' เอกสาร xml แรกไม่ถูกต้อง ไม่มีองค์ประกอบรากแม้ว่าจะดูเหมือนว่ามี เอกสาร canonical 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>

7

ลองใช้รหัสบล็อกนี้หากไฟล์. 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 ของฉัน คุณสามารถเปลี่ยนได้ตามความต้องการของคุณ


6

ผู้สังเกตการณ์ของ 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));
XmlData data = (XmlData)ser.Deserialize(XmlReader.Create(PathToCarsXml));

ขอบคุณ! คำตอบของคุณคือสิ่งที่ฉันต้องการเพราะฉันไม่ต้องการเปลี่ยนไฟล์บันทึกกิกะไบต์
โคลิน

แม้ว่าจะมีมูลค่าการกล่าวขวัญว่าโซลูชัน XmlSerializer นั้นสง่างามมาก แต่ก็ยอมรับว่ายังไม่เร็วมากและตอบสนองต่อข้อมูล Xml ที่ไม่คาดคิด ดังนั้นหากปัญหาของคุณไม่จำเป็นต้องทำการดีซีเรียลไลเซชั่นอย่างสมบูรณ์คุณควรพิจารณาใช้คลาส XmlReader ที่ใช้งานได้จริงและมีประสิทธิภาพเท่านั้นและวนลูปผ่านองค์ประกอบ <Car>
Kim Homann

5

ลองคลาสนี้โดยทั่วไปสำหรับการทำให้เป็นอันดับ 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;
    }
}

4

สำหรับมือใหม่

ฉันพบคำตอบที่นี่เพื่อเป็นประโยชน์อย่างมากที่บอกว่าฉันยังคงดิ้นรน (เพียงเล็กน้อย) เพื่อให้การทำงานนี้ ดังนั้นในกรณีที่ช่วยใครบางคนฉันจะแก้ปัญหาการทำงาน:

XML จากคำถามเดิม xml อยู่ในไฟล์ Class1.xml ไฟล์ a 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);
            }
        }
    }
}

หวังว่าจะช่วย :-)


1
มันใช้งานได้สำหรับฉัน นี่เป็นวิธีการทำงานที่สมบูรณ์แบบสำหรับอินพุต xml ที่กำหนด (ตามตัวอย่างของ OP) เช่นกัน [XmlElement ("Car")] เป็นแอตทริบิวต์ที่ถูกต้อง ในตัวอย่างอื่น ๆ พวกเขาใช้ XmlArray ฯลฯ ซึ่งไม่จำเป็นตราบใดที่เรามีคุณสมบัติที่กำหนดเป็นรถยนต์สาธารณะ [] รถยนต์ {รับ; ตั้ง; } และมันจะทำการ deserialize อย่างถูกต้อง ขอบคุณ
Diwakar Padmaraja

3

วิธีการเกี่ยวกับคลาสทั่วไปในการ deserialize เอกสาร 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;
}

ส่วนนี้อาจหรืออาจไม่จำเป็น เปิดเอกสาร XML ใน Visual Studio คลิกขวาที่ XML เลือกคุณสมบัติ จากนั้นเลือกไฟล์สคีมาของคุณ


1
สิ่งนี้ทำให้ฉันสามารถลดขนาดรหัสตรรกะทางธุรกิจได้เล็กน้อยและรวมศูนย์การทำงานในคลาสผู้ช่วยที่มีคลาส <T> ทั้งหมดที่ฉันสร้างขึ้น ฉันมี XML อยู่ในสายอักขระแล้วดังนั้นสามารถรวมเข้าไปในนี้: `สาธารณะคงที่ T LoadXMLFileIntoClass <T> (สตริง xmlData)` {`XmlSerializer serializer = XmlSerializer ใหม่ (typeof (T)); `return (T) serializer.Deserialize (StringReader ใหม่ (xmlData)); `} ขอบคุณ!
pwrgreg007


2

แนวคิดคือมีการจัดการทุกระดับสำหรับการดีซีเรียลไลเซชันโปรดดูตัวอย่างโซลูชันที่แก้ไขปัญหาที่คล้ายกันของฉัน

<?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 ตรวจสอบตัวอย่างนี้สำหรับการดีซีเรียลไลซ์เซชันหลายระดับ


1

หากคุณได้รับข้อผิดพลาดโดยใช้ xsd.exe ในการสร้างไฟล์ xsd ของคุณแล้วใช้คลาส XmlSchemaInference ตามที่กล่าวไว้ใน MSDN นี่คือการทดสอบหน่วยเพื่อสาธิต:

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

1

คุณสามารถเปลี่ยนได้เพียงคุณสมบัติเดียวสำหรับรถยนต์ Cars จาก 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

ทางออกของฉัน:

  1. ใช้Edit > Past Special > Paste XML As Classesในการรับชั้นเรียนในรหัสของคุณ
  2. ลองอะไรเช่นนี้: สร้างรายการของคลาสนั้น ( List<class1>) จากนั้นใช้XmlSerializerเพื่อเรียงลำดับรายการนั้นเป็น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"


1
async public static Task<JObject> XMLtoNETAsync(XmlDocument ToConvert)
{
    //Van XML naar JSON
    string jsonText = await Task.Run(() => JsonConvert.SerializeXmlNode(ToConvert));

    //Van JSON naar .net object
    var o = await Task.Run(() => JObject.Parse(jsonText));

    return o;
}

1
โปรดใส่คำตอบของคุณเสมอในบริบทแทนที่จะวางโค้ด ดูที่นี่สำหรับรายละเอียดเพิ่มเติม
gehbiszumeis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.