2015-04-09 2 views
0

Мне нужна помощь, чтобы найти хороший способ использования XmlReader. У меня есть простой XML:XmlReader конвертировать в хороший тип с тегом xsi

<?xml version="1.0"?> 
<ExtranetConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <DataParametersGroup GroupName="test"> 
    <DataParameter Name="testPrm" SqlParamName=":testPrm"> 
     <Value xsi:type="xsd:string">thisIsMyParam</Value> 
     <AdditionalValues> 
     <Description xsi:type="xsd:string">My Description</Description> 
     <Id xsi:type="xsd:int">10</Id> 
     </AdditionalValues> 
    </DataParameter> 
    </DataParametersGroup> 
</ExtranetConfig> 

По некоторым причинам, я должен сериализовать часть его

<AdditionalValues> 
    <Description xsi:type="xsd:string">My Description</Description> 
    <Id xsi:type="xsd:int">10</Id> 
    </AdditionalValues> 

с пользовательским классом, который реализует IXmlSerializable. Но я не понимаю, как получить хороший тип для Description и Id узлов с XmlReader.

Это мой последний тестовый код, на мой пользовательский класс:

private readonly Dictionary<string, object> dictionary = new Dictionary<string, object>(); 
     public void ReadXml(XmlReader reader) 
     { 
      reader.MoveToElement(); 

      var readElement = reader.ReadSubtree(); 
      readElement.MoveToContent(); 

      XmlNamespaceManager nsmanager = new XmlNamespaceManager(readElement.NameTable); 
      nsmanager.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema"); 
      nsmanager.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");    

      do 
      {    
       if (readElement.HasValue) 
       { 

        var val2 = readElement.ReadContentAs(readElement.ValueType, nsmanager);     
        var name2 = readElement.Name; 
        dictionary.Add(name2, val2); 
       } 
      } 
      while (readElement.Read()); 
     } 

Моя цель состоит в том, чтобы добавить в словарь все элементы между <AdditionalValues></AdditionalValues>. Текущий код частично выполняет задание, но всегда десериализуется в строковом типе.

+0

Знаете ли вы набор типов, которые могут отображаться в словаре? Кто они такие? Нужно ли сериализовать, а также десериализовать? – dbc

+0

Вы ищете общее решение, которое позволяет любому известному типу отображаться как значение в словаре, или вы ищете только десериализационные словари с целыми и строковыми значениями? – dbc

+0

В моем случае я использую только первичные типы, но сделаю его общим с любым сериализуемым типом, на который ссылается пространство имен xml, должно быть большим. – Manea

ответ

0

это мое фактическое решение, но я предполагаю, что это не чистый один, это «жёстко» ..

private readonly Dictionary<string, object> dictionary = new Dictionary<string, object>(); 

...

public void ReadXml(XmlReader reader) 
    { 
     reader.MoveToElement(); 
     string type = null; 
     string name = null; 
     object result = null; 
     while (reader.Read()) 
     { 

      if ((reader.NodeType == XmlNodeType.Element)) 
      { 
       type = reader.GetAttribute("xsi:type"); 
       name = reader.Name; 
      } 
      if ((reader.NodeType == XmlNodeType.Text)) 
      { 
       if (type != null) 
       { 
        switch (type.ToLower()) 
        { 
         case "xsd:int": 
          result = reader.ReadContentAsInt(); 
          break; 
         case "xsd:double": 
          result = reader.ReadContentAsDouble(); 
          break; 
         case "xsd:float": 
          result = reader.ReadContentAsFloat(); 
          break; 
         case "xsd:string": 
          result = reader.ReadContentAsString(); 
          break; 
         case "xsd:datetime": 
          result = reader.ReadContentAsDateTime(); 
          break; 
         case "xsd:boolean": 
          result = reader.ReadContentAsBoolean(); 
          break; 
         default: 
          result = reader.ReadContentAsString(); 
          break; 
        } 
        dictionary.Add(name, result); 
       }    
      } 
      if ((reader.NodeType == XmlNodeType.EndElement)) 
      { 
       if(reader.Name =="AdditionalValues") 
       { 
//Edit - add read before break or deserialisation will end here. 
reader.Read(); 
        break; 
       } 
      } 
     } 
    } 

Я не понимаю, как работать с namespaces и получить атрибут типа с XmlReader, reader.ValueType всегда (это значение по умолчанию). System.String ..

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