【问题标题】:XML Deserialization giving structure but not data in C#XML反序列化提供结构但不提供C#中的数据
【发布时间】:2018-05-23 05:50:55
【问题描述】:

我正在尝试反序列化一个 xml 文件。获取结构但没有数据。请帮忙。

以下是我正在使用的文件/类:

1。 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<Model     
  Content="ByBlock">
  <Units>
    <Unit
      UnitCategory="acceleration"
      Units="m/s2,cm/s2,ft/s2,g0" />   
    <Unit
      UnitCategory="angle"
      Units="radians,degrees,grads" />    
  </Units>
  <Modules>
    <Module
      Module="ControlValve">
      <Parameter
        Name="ValveCharacteristic"
        Type="Int">
        <Enumeration
          Tag="Parabolic"
          Value="4" />
        <Enumeration
          Tag="Hyperbolic"
          Value="5" />
      </Parameter>
      <Parameter
        Name="ValveCvOption"
        Type="Int">
        <Enumeration
          Tag="Set manually"
          Value="0" />
        <Enumeration
          Tag="Set from valve type and size"
          Value="1" />
      </Parameter>     
    </Module>
    <Module
      Module="Drum">
      <Parameter
        Name="VesselOrientation"
        Type="Int">
        <Enumeration
          Tag="Horizontal cylinder"
          Value="0" />
        <Enumeration
          Tag="Vertical cylinder"
          Value="1" />       
      </Parameter>
    </Module>
  </Modules>
  <Blocks>
  <Block
    ID="0"       
    Module="Drum">
    <Parameter
      Name="Diameter"         
      Value="1000.000000"/>
    <Parameter
      Name="Length"         
      Value="4000.000000"/>    
  </Block>
  <Block
    ID="0"        
    Module="ContinuousFlowCompressor">
    <Parameter
      Name="NominalSpeed"         
      Value="8950.000000"/>
    <Parameter
      Name="NominalFlow"         
      Value="2.783039" />   
  </Block>  
</Blocks>
  </Model>

2:类:

一个。模型类:

[XmlRoot("Model")]
public class Model
{     
    [XmlAttribute(AttributeName = "Content")]
    public string Content { get; set; }

    [XmlArray("Units")]
    [XmlArrayItem("Unit")]
    public List<Unit> Units { get; set; }

    [XmlArray("Modules")]
    [XmlArrayItem("Module")]
    public List<Module> Modules { get; set; }

    [XmlArray("Blocks")]
    [XmlArrayItem("Block")]
    public List<Block> Blocks { get; set; }
}

b.单元类:

[XmlRoot(ElementName = "Unit")]
public class Unit
{
    [XmlAttribute(AttributeName =  "UnitCategory")]
    public string UnitCategory { get; set; }
    [XmlAttribute(AttributeName =  "Units")]
    public string Units { get; set; }       
}

c。模块类:

[XmlRoot(ElementName = "Module")]
public class Module
{
    [XmlAttribute(AttributeName = "Module")]
    public string Modul { get; set; }

    [XmlArrayItem("Parameter")]
    public List<ModuleParameter> Parameters { get; set; }        
}

d。模块参数类:

[XmlRoot(ElementName = "Parameter")]
public class ModuleParameter
{
    [XmlAttribute(AttributeName =  "Name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName =  "Type")]

    public string Type { get; set; }
    [XmlArrayItem("Enumeration")]
    public List<Enumeration> Enumerations { get; set; }        
}

e。枚举类:

[XmlRoot(ElementName = "Enumeration")]
public class Enumeration
{
    [XmlAttribute(AttributeName = "Tag")]
    public string Tag { get; set; }

    [XmlAttribute(AttributeName =  "Value")]
    public string Value { get; set; }       
}

f。块类:

[XmlRoot(ElementName = "Block")]
public class Block
{
    [XmlAttribute(AttributeName =  "ID")]
    public string ID { get; set; }       

    [XmlAttribute(AttributeName =  "Module")]
    public string Module { get; set; }

    [XmlArrayItem("Parameter")]
    public List<BlockParameter> Parameters { get; set; }       
}

g. BlockParameter 类:

[XmlRoot(ElementName = "Parameter")]
public class BlockParameter
{
    [XmlAttribute(AttributeName =  "Name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName =  "Value")]
    public string Value { get; set; }        
}

我正在使用下面的代码来反序列化 xml 文件:

var serializer = new XmlSerializer(typeof(Model));
using (FileStream fs = File.OpenRead(file))
{
    var xmlClass = (Model)serializer.Deserialize(fs);
}

PS: 1. 请注意,我必须使用两个参数类:一个在模块中,另一个在块类中。 2. 我已将我的 XmlElement 修改为 XmlAttribute 以获取建议的属性,例如 Content、UnitCategory、Units 等。

【问题讨论】:

  • 最好的调试方式是用示例数据填充类,然后序列化。然后将序列化的数据与xml进行比较。第一个明显的问题是内容是一个属性而不是一个元素。
  • 这个 xml 是被序列化的还是只是一个示例 1?
  • 谢谢@jdweng,我已经更正了那部分。但尚未在参数列表中获取数据。

标签: c# xml xml-serialization


【解决方案1】:

更正一点,属性不是元素。
你可以找到其他的出现

[XmlRoot("Model")]
public class Model
{       
    //[XmlElement(ElementName = "Content")]
    [XmlAttribute(AttributeName = "Content")]
    public string Content { get; set; }

您也可以添加一个空的 C# 文件并选择编辑 |粘贴专用 | XML 作为类。不是最漂亮的代码,但至少它是有效的。比较有用。

【讨论】:

  • @bommlding:谢谢,我已经按属性更新了元素。现在我在我的反序列化对象中获取属性值。但是 Parameter 类还没有得到任何东西。
  • 不知道 Paste special 非常感谢! :-)
  • @WpfBee - 我不确定,但你的课程有多个问题......例如,应该只有一个 XmlRoot。使用 Paste-special 技巧替换您的代码或与它进行非常彻底的比较。
  • @bommelding - 我认为这是正确的。我已将模型类标记为仅作为根元素的根元素。我之前也使用过它,因为它工作正常。
【解决方案2】:

应该是这样的:

[XmlRoot("Model")]
public class Model
{
    [XmlAttribute(AttributeName = "Content")]
    public string Content { get; set; }

    [XmlArray("Units")]
    [XmlArrayItem("Unit")]
    public List<Unit> Units { get; set; }

    [XmlArray("Modules")]
    [XmlArrayItem("Module")]
    public List<Module> Modules { get; set; }

    [XmlArray("Blocks")]
    [XmlArrayItem("Block")]
    public List<Block> Blocks { get; set; }
}

[XmlRoot(ElementName = "Unit")]
public class Unit
{
    [XmlAttribute(AttributeName = "UnitCategory")]
    public string UnitCategory { get; set; }

    [XmlAttribute(AttributeName = "Units")]
    public string Units { get; set; }
}


[XmlRoot(ElementName = "Module")]
public class Module
{
    [XmlAttribute(AttributeName = "Module")]
    public string Modul { get; set; }

    [XmlElement("Parameter")]
    public List<ModuleParameter> Parameters { get; set; }
}

[XmlRoot(ElementName = "Parameter")]
public class ModuleParameter
{
    [XmlAttribute(AttributeName = "Name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName = "Type")]
    public string Type { get; set; }

    [XmlElement("Enumeration")]
    public List<Enumeration> Enumerations { get; set; }
}

[XmlRoot(ElementName = "Enumeration")]
public class Enumeration
{
    [XmlAttribute(AttributeName = "Tag")]
    public string Tag { get; set; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }
}

[XmlRoot(ElementName = "Block")]
public class Block
{
    [XmlAttribute(AttributeName = "ID")]
    public string ID { get; set; }

    [XmlAttribute(AttributeName = "Module")]
    public string Module { get; set; }

    [XmlElement("Parameter")]
    public List<BlockParameter> Parameters { get; set; }
}

[XmlRoot(ElementName = "Parameter")]
public class BlockParameter
{
    [XmlAttribute(AttributeName = "Name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }
}

解释: arrays/Lists without "containers" must be marked as XmlElement。举个例子:&lt;Module&gt; 有一个容器&lt;Modules&gt;,而&lt;Parameter&gt; 没有一个容器。直接添加到父元素中。

注意:正如@bommelding 所述,您可以删除所有[XmlRoot(...)] 属性。他们不需要。唯一需要的是 Model 类上的那个,但该类已经具有根元素的名称。

【讨论】:

  • @wpfbee 这个答案应该被接受,完美答案
  • xanatos:你为什么要保留所有这些 XmlRoots ?这有什么用吗?
  • @bommelding 不......但是OP把它们放进去,所以我把它们留在里面......也许他还有其他Xml,它们只是主要xml的子部分。它们都可以被删除,即使是Model 上的那个,因为该类与根元素具有相同的名称。
  • @xanatos - 非常感谢。这真的对我有用。我现在正在获取参数列表中的项目。
  • @xanatos - 非常感谢。这真的对我有用。我现在正在获取参数列表中的项目。两件事:一。发布的 XML 是原始文件 :) b。 ModuleParameter 和 BlockParameter 类,都是具有一些共同属性的 Parameter 类。我应该为模块和块使用单个参数类吗?如果我使用单个类,则 ModelParameter 类将获得具有空值的附加属性(这不是必需的)。如果我需要使用 2 个不同的类,请建议如何做?
【解决方案3】:

要获取标签的属性值,请将“XML 元素”更改为"XML Attribute"

EG:

[XmlElement(ElementName = "UnitCategory")]
public string UnitCategory { get; set; }

[XmlAttribute(AttributeName = "UnitCategory")]
public string UnitCategory { get; set; }

其他需要的字段。更改是标签、名称、类型等。

如果您通过序列化创建 XMl,请阅读 this

【讨论】:

  • 谢谢,我已经按属性更新了元素。现在我在我的反序列化对象中获取属性值。但是 Parameter 类还没有得到任何东西。
猜你喜欢
  • 2017-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多