将类序列化为XML,根据属性动态设置元素名称,基于其他属性动态设置xmltext

时间:2014-10-15 18:07:54

标签: c# c#-4.0 serialization visual-studio-2013 xml-serialization

是否可以将下面的类序列化为XML,并生成此输出?

挑战在于应该根据密钥(在本例中为doc_id和client_name)动态设置元素doc_id和client_name。相应的值应放在元素的文本中(在本例中为1,Client 1,12和Client 2)。

我可以重写这些类,但我必须生成这个XML。

<row>
  <doc_id>00000001</doc_id>
  <client_name>Client 1</client_name>
</row>
<row>
  <doc_id>000000012</doc_id>
  <client_name>Client 2</client_name>
</row>

    public struct SerializableKeyValuePair<T1, T2>
    {
        public T1 Key;

        public T2 Value;

        public SerializableKeyValuePair(T1 key, T2 value)
        {
            Key = key;
            Value = value;
        }
    }

    public class ActionParameter
    {
    [XmlElement("Row")]
        public List<SerializableKeyValuePair<object, object>> Rows;
    }

1 个答案:

答案 0 :(得分:0)

不幸的是,如果没有编写自己的序列化程序或只是手动处理读/写,你就不能这样做。

尝试使用预先制作的序列化程序是行不通的,因为它无法知道实际上是什么以及是什么。

但是,仍然可以将其与标准XmlSerializer结合使用。

public class ActionParameter
{
    [XmlElement("Row")]
    public List<XmlElement> RowElements
    {
        // The `get` is purely for the serializer. No reason for you to call it.
        get { return SomeMethodToSerializeToXmlDoc(Rows).ChildNodes.OfType<XmlElement>()
                                                                   .ToList(); }
        // The `set` from the Serializer will allow your "Rows" to be Deserialized.
        set { DeserializeKeyValues(value); }
    }

    [XmlIgnore]
    public List<SerializableKeyValuePair<string, string>> Rows { get; set; }

    void DeserializeKeyValues(List<XmlElement> elements) 
    {
         Rows = new List<SerializableKeyValuePair<string, string>>();
         foreach(XmlElement element in elements)
         {
             // Shouldn't your List of Rows, actually be another List of Key Values?
             // This call won't actually work. I think you need to really
             // loop through the children of this element as your key values.
             Rows.Add(new SerializableKeyValuePair<string, string>(element));
         }
    }
}


public struct SerializableKeyValuePair<T1, T2>
{
    public T1 Key;

    public T2 Value;

    public SerializableKeyValuePair(T1 key, T2 value)
    {
        Key = key;
        Value = value;
    }

    public SerializableKeyValuePair(XmlElement element)
    {
        Key = element.LocalName;
        var textNode = element.SelectSingleNode("text()");
        // Here you are also not limited to just text, since you have an actual Element, 
        // you could attempt to try and implement deserializing custom classes/objects.
        if (textNode != null)
            Value = SomeConvertForT2(textNode.Value);
    }
}

这基本上是伪代码,我很快就向你展示了一种可能的方式。