2008-11-20 28 views
7

Tôi muốn deserialize một tin nhắn XML có chứa một yếu tố có thể được đánh dấu nil="true" vào một lớp học với một tài sản của loại int?. Cách duy nhất tôi có thể làm cho nó hoạt động là viết loại NullableInt của riêng tôi thực hiện IXmlSerializable. Có cách nào tốt hơn để làm điều đó không?XmlSerializer có thể deserialize thành Nullable <int> không?

Tôi đã viết lên toàn bộ vấn đề và cách tôi giải quyết nó on my blog.

Trả lời

5

Tôi nghĩ bạn cần tiền tố nil = "true" với một không gian tên để XmlSerializer deserialise thành null.

MSDN on xsi:nil

<?xml version="1.0" encoding="UTF-8"?> 
<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="array"> 
    <entity> 
    <id xsi:type="integer">1</id> 
    <name>Foo</name> 
    <parent-id xsi:type="integer" xsi:nil="true"/> 
+0

Cảm ơn Phil, đã xử lý. Bây giờ tôi chỉ cần đưa anh chàng cung cấp các thông điệp để thêm không gian tên ... –

+0

Đừng lo lắng SCOA :-P Nếu bạn không thể thay đổi XML tại nguồn (nghe như bạn có thể), bạn có thể chuyển nó qua một phép biến đổi XSLT để thêm không gian tên tôi nghĩ ... –

+0

Có JENP, hóa ra thật khó để làm điều đó tại nguồn vì nó là một ứng dụng Rails sản xuất xml với 'to_xml'. Ngoài ra, thêm xsi: vào thuộc tính type làm cho .NET tìm kiếm một kiểu được gọi là 'mảng', không tồn tại. Vì vậy, cuối cùng nó sẽ được dễ dàng hơn để gắn bó với loại 'NullableInt' của tôi. –

3

sửa chữa của tôi là trước quá trình các nút, sửa chữa bất kỳ "nil" thuộc tính:

public static void FixNilAttributeName(this XmlNode @this) 
{ 
    XmlAttribute nilAttribute = @this.Attributes["nil"]; 
    if (nilAttribute == null) 
    { 
     return; 
    } 

    XmlAttribute newNil = @this.OwnerDocument.CreateAttribute("xsi", "nil", "http://www.w3.org/2001/XMLSchema-instance"); 
    newNil.Value = nilAttribute.Value; 
    @this.Attributes.Remove(nilAttribute); 
    @this.Attributes.Append(newNil); 
} 

tôi cặp vợ chồng này với một tìm kiếm đệ quy cho nút con, để cho bất kỳ XmlNode nào (hoặc XmlDocument) đã cho, tôi có thể đưa ra một cuộc gọi duy nhất trước khi deserialization. Nếu bạn muốn giữ cấu trúc trong bộ nhớ gốc chưa được sửa đổi, hãy làm việc với một Clone() của XmlNode.

+0

Điều đó làm việc rất tốt cho tôi, cảm ơn. Và rõ ràng cho Rails tiêu thụ. Tôi đã thực hiện một điều chỉnh nhỏ để kiểm tra các thuộc tính không null: XmlAttribute nilAttribute = null; nếu (@ this.Attributes! = Null) { nilAttribute = @ this.Attributes ["nil"]; } – Dylan

0

Cách lười biếng đặc biệt để làm điều đó. Rất mong manh vì một số lý do nhưng XML của tôi đủ đơn giản để đảm bảo việc khắc phục nhanh chóng và bẩn thỉu như vậy.

xmlStr = Regex.Replace(xmlStr, "nil=\"true\"", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:nil=\"true\""); 
Các vấn đề liên quan