【问题标题】:Element name or type as argument to XmlElementAttribute in System.Xml.Serialization元素名称或类型作为 System.Xml.Serialization 中 XmlElementAttribute 的参数
【发布时间】:2021-11-05 13:47:38
【问题描述】:

使用XmlSerializer反序列化时

案例 1: Presentation 包含 Slide 类型的子元素

<Presentation>
    <Slide>
        ...
    </Slide>
</Presentation>

nameof 获取正确的结果,即应该传递elementName。用typeof 替换它会得到不正确的结果。

public class Presentation
{
    ...
    [XmlElement(nameof(Slide))]
    public List<Slide> Slides { get; set; }
    ...
}

案例 2: Slide 包含从基类Shape 派生的TextBoxTable 类型的子元素

<Slide>
    <TextBox>
        ...
    </TextBox>
    <Table>
        ...
    </Table>
</Slide>

typeof 获取正确的结果,即应该传递type。用nameof 替换它会得到不正确的结果。

public class Slide
{
    ...
    [XmlElement(typeof(TextBox))]
    [XmlElement(typeof(Table))]
    public List<Shape> Shapes { get; set; }
    ...
}

任何人都可以解释上述内容吗?什么时候提供元素名称,什么时候提供类型?

【问题讨论】:

  • 我对这里实际询问的内容感到困惑。 typeofnameof 的作用之间是否存在混淆? nameoftypeof 都有很好的文档。
  • 并非如此。如果相应的未完成,则 XML 不会正确反序列化。

标签: c# .net xml attributes deserialization


【解决方案1】:

基于 C# 属性,XmlSerializer 构造函数通过使用反射分析类生成一对派生自 XmlSerializationReaderXmlSerializationWriter 的类[1]。然后还会在 XML 中的元素名称和 C# 中的类型之间建立映射[2]

XmlElementAttribute(string elementName, Type type) 用于集合时,每个属性对应一个这样的映射。这取决于每个属性的以下逻辑

  • 未指定类型时,从集合中元素的类型推断

  • ​如果指定了一个属性或没有指定一个属性(相同类型的对象的集合)

    • 未指定名称时,从属性名称推断
  • 如果指定了两个或多个属性(不同类型对象的集合)

    • 未指定名称时,从提供给属性或由属性推断的类型的名称推断

这在documentation of XmlAttribute中也有说明

请注意,当您多次应用 XmlElementAttribute 而不指定 ElementName 属性值时,元素将以可接受对象的类型命名。

现在参考 OP,

案例 1:

[XmlElement(nameof(Slide))]

类似于

[XmlElement("Slide", typeof(Slide))]

typeof 替换它类似于

[XmlElement("Slides", typeof(Slide))]

这意味着我们需要将 "Slides" 指定为 XML 中的元素名称,而不是 "Slide",因此结果不正确。

案例 2:

[XmlElement(typeof(TextBox))]
[XmlElement(typeof(Table))]

类似于

[XmlElement("TextBox", typeof(TextBox))]
[XmlElement("Table", typeof(Table))]

nameof 替换它类似于

[XmlElement("TextBox", typeof(Shape))]
[XmlElement("Table", typeof(Shape))]

在这里,在TextBoxTable 之间映射Shape 类型的内容是不明确的。因此,映射本身无法建立,代码退出。

【讨论】:

    猜你喜欢
    • 2019-09-10
    • 1970-01-01
    • 2012-07-19
    • 2014-04-09
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 2013-12-12
    • 1970-01-01
    相关资源
    最近更新 更多