2010-05-11 74 views
2

我正在构建一个返回XML(无SOAP,无ATOM,只是普通的旧XML)的服务。假设我的域对象已经充满了数据,只需要将它们转换为XML格式即可。我对.NET有什么选择?.NET中的XML序列化选项

要求:

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

下面是我看到它们作为时刻的选项。更正/增加将是非常受欢迎的。

  • 字符串连接 - 算了吧,这是个玩笑:)
  • LINQ的2 XML - 完全控制,但相当多的手工编写的代码,就需要单位的良好套件测试
  • 查看引擎在ASP.NET MVC(甚至是理论上的Web窗体)中,逻辑在控制器中。这是一个如何构造它的问题,我可以在我的控制器中使用简单的规则引擎,在每个可能的输出中使用一个视图模板,或者直接在模板中使用决策逻辑。两者都有好处和坏处。
  • XML序列化 - 我不知道这里的灵活性
  • 数据契约从WCF - 不知道的弹性选择,再加上他们会在一个简单的ASP.NET MVC应用程序(非WCF工作服务)?它们现在是标准XML序列化的超集吗?
  • 如果存在,一些XML到对象映射器。我越想越想,我正在寻找这样的东西,但我找不到合适的东西。

任何意见/其他选项?

+0

你说你想要的“一个XML到对象的映射“但你也表示你只想将对象序列化为XML,而不是其他方式。这是什么?实际上,XmlSerializer和DataContractSerializer都做* * *;尽管应用程序只在一个方向上使用它们是很常见的。 – Cheeso 2010-05-11 12:28:37

+0

你是对的,这是令人困惑的。我只需要对象到XML的方向。 – Borek 2010-05-11 15:23:19

回答

6

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

然后,序列化的,一个实例为一个字符串,例如:

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

结果:

<pdata> 
    <Name>Gordon Brown</Name> 
    <Age>57</Age> 
    <xaddr city="London">10 Downing St., 1QR 3E4</xaddr> 
</pdata> 
+0

最糟糕的情况是,如果XML序列化程序没有提供您想要的内容,则可以随时编写您自己的序列化程序。 – 2010-05-11 10:29:11

+0

对不起,我错误地格式化了XML示例(地址等),但感谢您的回复。难道你不知道,数据合同是否与这个旧的XML序列化类似或者更灵活? – Borek 2010-05-11 11:51:42

+0

您也可以使用DataContractSerializer。它是相似的。在某些方面DCS比XmlSerializer更灵活;在大多数情况下,更少。 http://www.danrigsby.com/blog/index.php/2008/03/07/xmlserializer-vs-datacontractserializer-serialization-in-wcf/ – Cheeso 2010-05-11 12:16:53