【问题标题】:How to use ShouldSerialize[MemberName]() to Conditionally Serialize Element Within Property of Object Where Property is a List?如何使用 ShouldSerialize[MemberName]() 有条件地序列化对象属性中的元素,其中属性是列表?
【发布时间】:2019-12-20 21:26:48
【问题描述】:

我有一个类“Hospitalization”,我需要将其序列化为 XML 字符串。该类有一个属性“ActiveDiagnoses”,它是一个类型为“DiagnosisCode”的列表。

在该集合中,只有具有属性 Order 且值小于 3 的元素才应包含在序列化字符串中。

这里是一个例子(它不能只序列化小于 3 的 DiagnosisCodes):

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

namespace XmlConditionalSerializationOnListExample
{
    [XmlRoot]
    public class Hospitalization
    {
        public string PatientName { get; set; }
        public DateTime AdmitDate { get; set; }

        [XmlElement("DiagnosisCode")]
        public List<DiagnosisCode> ActiveDiagnoses { get; set; }
    }

    public class DiagnosisCode
    {
        public string Code { get; set; }
        public string CodeSet { get; set; }

        [XmlIgnore]
        public int Order { get; set; }

    }

    class Program
    {

        static void Main(string[] args)
        {
            Hospitalization hospitalization = new Hospitalization() { PatientName = "Test Patient", AdmitDate = DateTime.Now.Date };

            List<DiagnosisCode> Dxs = new List<DiagnosisCode>()
            {
                new DiagnosisCode(){Code="Z99.81", CodeSet="ICD10", Order = 1}
                ,new DiagnosisCode(){Code="Z99.0", CodeSet="ICD10", Order = 2}
                ,new DiagnosisCode(){Code="Z98.5", CodeSet="ICD10", Order = 3}
            };

            hospitalization.ActiveDiagnoses = Dxs;

            string HospitalizationXml = String.Empty;
            XmlSerializer Ser = new XmlSerializer(hospitalization.GetType());
            //XmlSerializer Ser = new XmlSerializer(Hospitalization);

            using (StringWriter writer = new StringWriter())
            {
                Ser.Serialize(writer, hospitalization);
                HospitalizationXml = writer.ToString();
            }

            Console.WriteLine("Hospitalization object as represented by XML string:\n{0}", HospitalizationXml);

            Console.ReadKey();
        }
    }

}

我的第一个想法是设置更改我将 Dxs 变量分配为 ActiveDiagnoses 属性的值的行,该循环将有条件地向每个 DiagnosisCode 添加一个 XmlIgnore 属性,其 order 属性值高于 2 但显然你@ 987654321@.

然后我找到了几个使用 ShouldSerialize() 方法来确定属性是否会被序列化的示例:

Example 1 Example 2

我的场景与上面链接的场景之间的区别在于,示例 1 为不是 List 的属性添加了 ShouldSerialize() 方法,虽然第二个确实为 List 属性添加了 ShouldSerialize() 方法,但该方法确定天气是否序列化整个元素列表,而不是其中的特定元素。

我尝试将以下方法添加到 DiagnosisCode 类:

public bool ShouldSerializeDiagnosisCode()
{
     return Order < 3 ? true : false;
}

但是没有效果。我试图将该方法移至 Hospitalization 类,但正如预期的那样出现编译错误,因为编译器不知道我在 Order 属性中指的是什么。

我确实通过执行以下操作找到了解决方法:

1:将 Hospitalization 类更改为具有两个 DiagnosisCode 对象列表,其中一个被标记为在序列化为 XML 时被忽略。

[XmlRoot]
public class Hospitalization
{
    public string PatientName { get; set; }
    public DateTime AdmitDate { get; set; }

    [XmlElement("DiagnosisCode")]
    public List<DiagnosisCode> ActiveDiagnoses { get; set; }

    [XmlIgnore]
    public List<DiagnosisCode> NonBillableDiagnoses { get; set; }
}

2:更改我的 Main() 方法以在循环中添加每个诊断,并根据当时的 OrderIndex 确定将 DiagnosisCode 添加到两个列表中的哪一个。

//hospitalization.ActiveDiagnoses = Dxs;

hospitalization.ActiveDiagnoses = new List<DiagnosisCode>();
hospitalization.NonBillableDiagnoses = new List<DiagnosisCode>();

foreach (DiagnosisCode dx in Dxs)
{
    if (dx.Order < 3)
    {
        hospitalization.ActiveDiagnoses.Add(dx);
    }
    else
    {
        hospitalization.NonBillableDiagnoses.Add(dx);
    }
}

该解决方案工作正常,但我想知道是否有一种方法可以按照我上面描述的方式使用 ShouldSerialize 方法。

您可以提供任何帮助/建议,我将不胜感激。

【问题讨论】:

标签: c# xml serialization


【解决方案1】:

这不是ShouldSerialize 模式的预期目的。如果您需要在序列化之前转换数据,只需在代码中进行,就像您已经在做的那样。

如果您想将其保留在您的 Hospitalization 类中,您可以在属性的 getter 中过滤列表,如下所示:

[XmlRoot]
public class Hospitalization
{
    public string PatientName { get; set; }
    public DateTime AdmitDate { get; set; }

    [XmlIgnore]
    public List<DiagnosisCode> ActiveDiagnoses { get; set; }

    [XmlElement("DiagnosisCode")]
    public List<DiagnosisCode> SerializableDiagnoses { get { return ActiveDiagnoses.Where(d => d.Order <= 2).ToList(); } }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多