.NET中的XML序列化选项

Bor*_*ard 2 .net xml-serialization

我正在构建一个返回XML的服务(没有SOAP,没有ATOM,只是简单的旧XML).假设我的域对象已经填充了数据,只需要将它们转换为XML格式.我在.NET上有什么选择?

要求:

  • 转型不是1:1.假设我有一个Address类型的Address属性,其中包含Line1,City,Postcode等嵌套属性.这可能需要产生类似XML <xaddr city="...">Line1, Postcode</xaddr>,即完全不同的XML .
  • 某些XML元素/属性是有条件的,例如,如果Customer小于18,则XML需要包含一些其他信息.
  • 我只需要将对象序列化为XML,另一个方向(XML到对象)并不重要
  • 某些技术,即数据合同使用.NET属性.其他配置方式(外部XML配置,伙伴类等)将是一个加号.

以下是我认为是时刻的选项.更正/补充将非常受欢迎.

  • 字符串连接 - 忘记它,这是一个笑话:)
  • Linq 2 XML - 完全控制但是相当多的手写代码,需要良好的单元测试套件
  • 在ASP.NET MVC中查看引擎(理论上甚至是Web Forms),逻辑在控制器中.这是一个如何构建它的问题,我可以在我的控制器中使用简单的规则引擎,每个可能的输出都有一个视图模板,或者直接在模板中使用决策逻辑.两者都有好处和缺点.
  • XML序列化 - 我不确定这里的灵活性
  • 来自WCF的数据合同 - 不确定灵活性,还能在简单的ASP.NET MVC应用程序(非WCF服务)中工作吗?它们现在是标准XML序列化的超集吗?
  • 如果存在,则使用一些XML到对象映射器.我越想它越多,我认为我正在寻找这样的东西,但我找不到合适的东西.

有任何评论/其他选择吗?

Che*_*eso 8

Xml序列化很好地工作.您使用属性来配置它.

您可以有条件地包含元素.

编辑:我已更新代码以反映您更新的问题.

[XmlRoot("pdata")]  // this element name used if serialized to doc root
public class PersonalData
{
     [XmlElement]  // with no name here, elt name = prop name
     public string Name;

     [XmlElement]  // with no name here, elt name = prop name
     public int Age;

     [XmlElement("xaddr")]  // override xml element name 
     public AddressData Address;

     [XmlElement] 
     public Under18Info Other {get; set;}

     // serialize the above element, only if Age < 18
     [XmlIgnore] // do not serialize the *Specified" property in any case
     private bool OtherSpecified {
        get { return Age < 18; }
     }
}

public class AddressData
{
     [XmlIgnore]   // do not serialize (see Composite prop)
     public string Line1 { get; set;}

     [XmlAttribute("city")] // serialize as an attribute on the parent 
     public string City {get; set;}

     [XmlIgnore]   // do not serialize 
     public string Postcode {get; set;}

     [XmlText]   // serialize as the Text node
     public string Composite 
     {
        get { return Line1 + ", " + Postcode; }
        set {
          var split = value.Split(',');
          Line1 = split[0];
          Postcode= split[1];
        }
     }
}
Run Code Online (Sandbox Code Playgroud)

然后,将其实例序列化为字符串,例如:

var pdata = new PersonalData
    {
        Name = "Gordon Brown",
        Age = 57,
        Address = new AddressData
        {
            Line1 = "10 Downing St.",
            Postcode = "1QR 3E4",
            City = "London"
        }
    };

var ns= new System.Xml.Serialization.XmlSerializerNamespaces();
ns.Add( "", "");
var s1 = new XmlSerializer(typeof(PersonalData));
var builder = new System.Text.StringBuilder();
var xmlws = new System.Xml.XmlWriterSettings { OmitXmlDeclaration = true, Indent= true };
using ( var writer = System.Xml.XmlWriter.Create(builder, xmlws))
{
    s1.Serialize(writer, pdata, ns);
}
string xml = builder.ToString();
Run Code Online (Sandbox Code Playgroud)

结果:

<pdata>
  <Name>Gordon Brown</Name>
  <Age>57</Age>
  <xaddr city="London">10 Downing St., 1QR 3E4</xaddr>
</pdata>
Run Code Online (Sandbox Code Playgroud)