2015-05-21 3 views
-1

Мне нужно сгенерировать следующий XML точно. Обратите внимание, что каждый элемент ввода должен быть строкой или логическим.Последовательный словарь для 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.

Сейчас я serialising данные, используя следующее:

Object Model

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 в объектной модели, позволит мне сохранить эти значения, однако это добавит еще один элемент в XML, который не поможет, поскольку XML должен быть точно таким же, как показанный на самом верху.

Мои исследования в этой проблеме привели к тому, что я должен использовать словарь. Я правильно понял, что мне нужен словарь? Если да, то как мне начать сериализацию словаря через объектную модель.

Большое спасибо всем, кто может помочь.

+1

Просьба указать [хороший, _minimal_, _complete_ пример кода] (http: // stackover flow.com/help/mcve), который надежно воспроизводит проблему. Обратите внимание, что даже если этот вопрос якобы связан с сериализацией XML, вы не показываете никакого кода, который фактически сериализует любые данные! Кроме того, в вашем примере кода ничего нет, что говорит о наличии любого текста или других значений, читающих «8,6,1». Почему вы ожидаете, что это появится в XML? –

+0

вот что я пытаюсь добавить. Я не предоставил код, который сериализует данные, потому что с этим кодом нет проблемы. Проблема связана с объектной моделью. – CodeMonkey

+0

Итак, вам все равно, как выглядит тип объекта в памяти? Тогда я бы сказал, что ответ, который уже есть, должен быть достаточным. Если это не так, то ясно, что у вас есть некоторые детали, оставшиеся без вашего вопроса. –

ответ

0

Update

Учитывая, что ваш Item класс может содержать различные типы примитивных данных, я собираюсь предложить моделирования как содержащий объект типа IConvertible - т.е. объект, который может быть преобразован из и к строке. Тогда вы можете сериализовать это значение строки как character data каждого Item элемента (8,6,1 в вашем примере), украшая соответствующее свойство с [XmlTextAttribute] атрибута:

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 элемента (8,6,1 в вашем примере), украшая соответствующее свойство с атрибутом [XmlTextAttribute].Это позволяет добавить дополнительные 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> 
+0

я на самом деле нужно добавить несколько элементов более Элемента к ISKeyValueList например True True Как я могу измените свой пример, чтобы принять логические значения и строки. Я полагаю, что 8, 6, 1 должна быть строкой, если вы посмотрите на атрибут type. – CodeMonkey

+0

Можете ли вы обновить свой вопрос, включив в него примеры всех необходимых XML-выходов? – dbc

+0

Готово. Я добавил другие элементы ввода в XML в начале моего вопроса. Огромное спасибо. – CodeMonkey

Смежные вопросы