XmlReader转换为由xsi类型标记的良好类型

时间:2015-04-09 13:43:47

标签: c# xml xmlreader

我需要一些帮助才能找到使用XmlReader的好方法。我有一个简单的XML:

<?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获取IdXmlReader个节点的良好类型。

这是我在我的自定义类中的最后一次代码测试:

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>。当前代码部分执行此任务,但始终以字符串类型反序列化。

1 个答案:

答案 0 :(得分: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;
                }
            }
        }
    }

我不明白如何使用命名空间并使用XmlReader获取type属性,reader.ValueType始终是(默认值)System.String ..