我需要完全生成以下XML。请注意,每个输入元素必须是字符串或布尔值。
<Userdata version="1.00">
<ISKeyValueList>
<Item type="String" key="AgeOfDependents">8,6,1<Item/>
<Item type="Boolean" key="SecuritiesInPosession"> True </Item>
<Item type="Boolean" key="SecuritiesOwners"> True </item>
</ISKeyValueList>
</Userdata>
除输入元素外,我可以正确生成上述大部分XML。我当前的方法生成以下内容:
<Item type="String" key="AgeOfDependents"/>
如您所见,Item元素不包含文本值8,6,1。
我目前正在使用以下代码序列化数据:
对象模型
public class finClient
{
[XmlAttribute("version")]
public string version = "1.00";
public UserData Userdata;
}
public class UserData
{
[XmlAttribute("version")]
public string version = "1.00";
public List<Item> ISKeyValueList;
}
public class Item
{
[XmlAttribute("type")]
public string type;
[XmlAttribute("key")]
public string key;
}
C#
以下是我构建对象的方法,后来我将其序列化为XML
Userdata = new UserData()
{
ISKeyValueList = new List<Item>()
{
new Item()
{
type = "String", key = "AgeOfDependents"
}
}
}
我知道在对象模型中向Item对象添加另一个元素,例如Value,这将允许我存储这些值,但这会在XML中添加另一个元素,因为XML需要准确无需帮助与最上面显示的相同。
我对这个问题的研究让我觉得我需要使用字典。我认为我需要一本字典吗?如果是这样,我如何通过对象模型序列化字典。
非常感谢能够提供帮助的任何人。
答案 0 :(得分:0)
<强>更新强>
鉴于您的Item
类可以包含不同类型的原始数据,我建议将其建模为包含IConvertible
类型的对象 - 即可以转换的对象来自和到一个字符串。然后,您可以通过使用character data属性修饰相应的属性,将该字符串值序列化为每个Item
元素的[XmlTextAttribute]
(示例中为8,6,1
):
public class Item
{
TypeCode _type = TypeCode.Empty; // When deserializing, attributes are deserialized before element values, which allows the _type to be set before the XmlValue is read.
IConvertible _value = null;
static TypeCode GetItemType(IConvertible value)
{
if (value == null)
return TypeCode.Empty;
return value.GetTypeCode();
}
[XmlAttribute("type")]
public TypeCode type
{
get
{
return _type;
}
set
{
_type = value;
if (GetItemType(_value) != _type)
_value = null;
}
}
[XmlAttribute("key")]
public string key { get; set; }
[XmlIgnore]
public IConvertible Value
{
get
{
return _value;
}
set
{
_type = GetItemType(value);
_value = value;
}
}
[XmlText]
public string XmlValue
{
get
{
if (_value == null)
return null;
return Value.ToString(CultureInfo.InvariantCulture);
}
set
{
if (value == null)
_value = null;
else
{
_value = (IConvertible)Convert.ChangeType(value, _type, CultureInfo.InvariantCulture);
}
}
}
}
然后是以下测试用例:
string xml = @"<Userdata version=""1.00"">
<ISKeyValueList>
<Item type=""String"" key=""AgeOfDependents"">8,6,1</Item>
<Item type=""Boolean"" key=""SecuritiesInPosession""> True </Item>
<Item type=""Boolean"" key=""SecuritiesOwners""> True </Item>
</ISKeyValueList>
</Userdata>
";
var userdata = xml.LoadFromXML<UserData>();
Debug.WriteLine(userdata.GetXml(true));
产生以下输出:
<Userdata version="1.00"> <ISKeyValueList> <Item type="String" key="AgeOfDependents">8,6,1</Item> <Item type="Boolean" key="SecuritiesInPosession">True</Item> <Item type="Boolean" key="SecuritiesOwners">True</Item> </ISKeyValueList> </Userdata>
原始答案
您可以通过使用character data属性修饰相应的属性,将字符串(或其他基元或枚举类型)序列化为元素的[XmlTextAttribute]
(示例中为8,6,1
)。这允许您将额外的Value
属性添加到Item
类,如下所示:
public class Item
{
[XmlAttribute("type")]
public string type;
[XmlAttribute("key")]
public string key;
[XmlIgnore] // Do not output the list to XML directly
public List<int> Values { get; set; }
[XmlText] // Instead, output the list as a comma-separated string in the XML element's text value.
public string XmlValue
{
get
{
if (Values == null)
return null;
return string.Join(",", Values.Select(i => XmlConvert.ToString(i)).ToArray());
}
set
{
if (value == null)
Values = null;
else
{
Values = value.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => XmlConvert.ToInt32(s)).ToList();
}
}
}
}
然后是以下课程:
var client = new finClient { Userdata = new UserData { ISKeyValueList = new List<Item> { new Item { type = "String", key = "AgeOfDependents", Values = new List<int> { 8, 6, 1 } } } } };
将序列化为以下XML:
<finClient version="1.00"> <Userdata version="1.00"> <ISKeyValueList> <Item type="String" key="AgeOfDependents">8,6,1</Item> </ISKeyValueList> </Userdata> </finClient>