Helpex - Trao đổi & giúp đỡ Đăng nhập
35

Tôi có một tập hợp các lớp mà tôi muốn tuần tự hóa thành tệp XML. Nó trông giống như thế này:

public class Foo
{
  public List<Bar> BarList { get; set; }
}

Trong đó một thanh chỉ là một trình bao bọc cho một tập hợp các thuộc tính, như thế này:

public class Bar
{
  public string Property1 { get; set; }
  public string Property2 { get; set; }
}

Tôi muốn đánh dấu điều này để nó xuất ra một tệp XML - tệp này sẽ được sử dụng cho cả tính bền bỉ và cũng để hiển thị các cài đặt qua XSLT thành một dạng đẹp mắt mà con người có thể đọc được.

Tôi muốn có được một biểu diễn XML đẹp như sau:

<?xml version="1.0" encoding="utf-8"?>
<Foo>
  <BarList>
    <Bar>
      <Property1>Value</Property1>
      <Property2>Value</Property2>   
    </Bar>
    <Bar>
      <Property1>Value</Property1>
      <Property2>Value</Property2>   
    </Bar>
  </Barlist>
</Foo>

tất cả các Quán bar trong Barlist đều được viết ra với tất cả các thuộc tính của chúng. Tôi khá chắc chắn rằng tôi sẽ cần một số đánh dấu trên định nghĩa lớp để làm cho nó hoạt động, nhưng dường như tôi không thể tìm thấy sự kết hợp phù hợp.

Tôi đã đánh dấu Foo bằng thuộc tính

[XmlRoot("Foo")]  

list<Bar>với thuộc tính

[XmlArray("BarList"), XmlArrayItem(typeof(Bar), ElementName="Bar")]

trong một nỗ lực để nói với Serializer những gì tôi muốn xảy ra. Tuy nhiên, điều này dường như không hoạt động và tôi chỉ nhận được một thẻ trống, trông như thế này:

<?xml version="1.0" encoding="utf-8"?>
<Foo> 
  <Barlist />
</Foo>

Tôi không chắc liệu thực tế tôi đang sử dụng Thuộc tính tự động có ảnh hưởng gì không hay việc sử dụng thuốc gốc có yêu cầu bất kỳ phương pháp điều trị đặc biệt nào hay không. Tôi đã làm điều này để làm việc với các kiểu đơn giản hơn như danh sách các chuỗi, nhưng danh sách các lớp cho đến nay vẫn không có tôi.

35 hữu ích 0 bình luận 81k xem chia sẻ
31

Chỉ để kiểm tra, bạn đã đánh dấu Bar là [Có thể sắp xếp thứ tự] chưa?

Ngoài ra, bạn cần một ctor ít tham số trên Bar, để deserialize

Rất tiếc, tôi đã sử dụng:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {

        Foo f = new Foo();

        f.BarList = new List<Bar>();

        f.BarList.Add(new Bar { Property1 = "abc", Property2 = "def" });

        XmlSerializer ser = new XmlSerializer(typeof(Foo));

        using (FileStream fs = new FileStream(@"c:\sertest.xml", FileMode.Create))
        {
            ser.Serialize(fs, f);
        }
    }
}

public class Foo
{
    [XmlArray("BarList"), XmlArrayItem(typeof(Bar), ElementName = "Bar")]
    public List<Bar> BarList { get; set; }
}

[XmlRoot("Foo")]
public class Bar
{
    public string Property1 { get; set; }
    public string Property2 { get; set; }
}

Và điều đó tạo ra:

<?xml version="1.0"?>
<Foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <BarList>
    <Bar>
      <Property1>abc</Property1>
      <Property2>def</Property2>
    </Bar>
  </BarList>
</Foo>
31 hữu ích 1 bình luận chia sẻ
4

Mọi thứ trông rất tuyệt. Như @Carl đã nói, bạn cần phải thêm attibute [Serializable] vào các lớp của mình, nhưng khác với việc tạo XML của bạn phải hoạt động.

Foo

[Serializable]
[XmlRoot("Foo")]
public class Foo
{
    [XmlArray("BarList"), XmlArrayItem(typeof(Bar), ElementName = "Bar")]
    public List<Bar> BarList { get; set; }
}

Quán ba

[Serializable]
public class Bar
{
    public string Property1 { get; set; }
    public string Property2 { get; set; }
}

Mã để kiểm tra

Foo f = new Foo();
f.BarList = new List<Bar>();
f.BarList.Add(new Bar() { Property1 = "s", Property2 = "2" });
f.BarList.Add(new Bar() { Property1 = "s", Property2 = "2" });

FileStream fs = new FileStream("c:\\test.xml", FileMode.OpenOrCreate);
System.Xml.Serialization.XmlSerializer s = new System.Xml.Serialization.XmlSerializer(typeof(Foo));
s.Serialize(fs, f);

Đầu ra

<?xml version="1.0" ?> 
<Foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <BarList>
        <Bar>
            <Property1>s</Property1> 
            <Property2>2</Property2> 
        </Bar>
        <Bar>
            <Property1>s</Property1> 
            <Property2>2</Property2> 
        </Bar>
    </BarList>
</Foo>
4 hữu ích 2 bình luận chia sẻ
2
var xmlfromLINQ = new XElement("BarList",
            from c in BarList 
            select new XElement("Bar",
                new XElement("Property1", c.Property1),
                new XElement("Property2", c.Property2)
             ));
2 hữu ích 0 bình luận chia sẻ
1

Đã hơn 5 năm kể từ khi mục này được đăng. Tôi đưa ra kinh nghiệm của mình từ tháng 7 năm 2013 (.NET Framework 4.5). Đối với giá trị của nó và đối tượng mà nó có thể quan tâm:

Khi tôi định nghĩa một lớp như vậy: (Mã VB.Net)

<Serializable> Public Class MyClass
    Public Property Children as List(of ChildCLass)
    <XmlAttribute> Public Property MyFirstProperty as string
    <XmlAttribute> Public Property MySecondProperty as string
End Class

<Serializable> Public Class ChildClass
    <XmlAttribute> Public Property MyFirstProperty as string
    <XmlAttribute> Public Property MySecondProperty as string
End Class

Với định nghĩa này, lớp được (de) tuần tự hóa mà không gặp bất kỳ vấn đề nào. Đây là XML xuất phát từ đây:

<MyClass> MyFirstProperty="" MySecondProperty=""
    <Children>
        <ChildClass> MyFirstProperty="" MySecondProperty=""
        </ChildClass>
   </Children>
</MyClass>

Tôi chỉ mất hai ngày để tìm ra giải pháp là loại bỏ <XmlElement>tiền tố của các phần tử Danh sách (của T).

1 hữu ích 4 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ c# xml serialization , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading