c# - 将多项选择元素从 XML 序列化为 C#

标签 c# xml serialization

我有这个架构

<xs:complexType name="FatherElement">
    <xs:sequence>
        <xs:element ref="FatherClass"/>
        <xs:choice>
            <xs:sequence>
                <xs:element ref="FatherType"/>
                <xs:element ref="FatherLocation" minOccurs="0"/>
                <xs:element ref="FatherTypeDescription" minOccurs="0"/>
            </xs:sequence>
            <xs:sequence>
                <xs:element ref="FatherLocation"/>
                <xs:element ref="FatherTypeDescription" minOccurs="0"/>
            </xs:sequence>
            <xs:element ref="FatherTypeDescription"/>
        </xs:choice>
        <xs:element ref="FatherBasis"/>
        <xs:element ref="FatherRole" minOccurs="0"/>
        <xs:element name="Extension" type="FatherElement_ExtensionType" minOccurs="0"/>
    </xs:sequence>
</xs:complexType>

我正在尝试使用此 C# 映射进行映射(拥有所有字段会很好,但我现在不需要它们)

[System.Serializable()]
[System.ComponentModel.DesignerCategory("code")]
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.lol.com/Standards/lol/1")]
public class FatherElement
{
    /// <remarks/>
    public string FatherTypeDescription { get; set; }

    /// <remarks/>
    public string FatherType { get; set; }

    /// <remarks/>
    public FatherLocation FatherLocation { get; set; }
}


[System.Serializable()]
[System.ComponentModel.DesignerCategory("code")]
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.lol.com/Standards/lol/1")]
public class FatherLocation
{
    /// <remarks/>
    public FatherLocationLocation Location { get; set; }
}


[System.Serializable()]
[System.ComponentModel.DesignerCategory("code")]
[System.Xml.Serialization.XmlType(AnonymousType = true, Namespace = "http://www.lol.com/Standards/lol/1")]
public class FatherLocationLocation
{
    /// <remarks/>
    public string Country { get; set; }
}

我得到的传入 XML 值是

<FatherElement>
    <FatherClass>classValue</FatherClass> 
    <FatherType>typeValue</FatherType> 
    <FatherTypeDescription>typeValueDesc</FatherTypeDescription> 
    <FatherBasis>basisValue</FatherBasis> 
    <FatherRole>RoleValue</FatherRole> 
</FatherElement>

我得到的是:

<FatherElement>
    <FatherTypeDescription>typeValueDesc</FatherTypeDescription>
    <FatherType>typeValue</FatherType>
  </FatherElement>

当我尝试根据 SDC 对其进行验证时,收到一条错误消息,指出元素 FatherElement 具有无效的子 FatherTypeDescription。

我尝试从 XSD 生成 C# 映射,但它生成的代码将选择转换为类型对象的元素,并且我想保留强类型。

有什么想法吗?

最佳答案

<xs:choice>生成类时仍然存在问题。问题在于所选元素的装箱和命名。我建议一个解决方法。

据我了解,您想在三种可能性之间进行选择:

  1. 父亲有Type并且可以有LocationDescription

  2. 父亲有Location并且可以Description

  3. 父亲有Description

问题是,您选择中定义的序列类型将不会被正确识别(就像 MaPi 评论的那样,您必须使用 ItemName-Enum 和 Item)。 您可以将 coosable 序列移动到一个元素中,以解释 VS 将它们作为单个对象进行处理。这是一个示例(我确实用字符串替换了复杂类型以实现可编译/可生成的示例):

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="FatherElement">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="FatherClass" type="xs:string"/>
                <xs:choice> <!-- In this choice we can choose 3 different elements -->
                    <xs:element name="CompleteFather"> <!-- 1 -->
                        <xs:complexType>
                            <xs:sequence>
                                <xs:element name="FatherType" type="xs:string"/>
                                <xs:element name="FatherLocation" type="xs:string" minOccurs="0"/>
                                <xs:element name="FatherTypeDescription" type="xs:string" minOccurs="0"/>
                            </xs:sequence>
                        </xs:complexType>
                    </xs:element>
                    <xs:element name="UncompletaFather"> <!-- 2 -->
                        <xs:complexType>
                            <xs:sequence>
                                <xs:element name="FatherLocation" type="xs:string"/>
                                <xs:element name="FatherTypeDescription" type="xs:string" minOccurs="0"/>
                            </xs:sequence>
                        </xs:complexType>
                    </xs:element>
                    <xs:element name="FatherTypeDescription" type="xs:string"/> <!-- 3 -->
                </xs:choice>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

这里是一些示例 C# 代码。

FatherElement e = new FatherElement();
e.FatherClass = "Some Element";

// Here we choose our element in our choice. It'll be boxed into an object.
e.Item = new FatherElementCompleteFather()
{
    FatherLocation = "loc",
    FatherType = "type",
    FatherTypeDescription = "desc"
};

string filePath = @"C:\Temp\test.xml";
XmlSerializer x = new XmlSerializer(e.GetType());

using (var sw = new StreamWriter(filePath))
    x.Serialize(sw, e);

关于c# - 将多项选择元素从 XML 序列化为 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55490600/

相关文章:

c# - WP8.1和WP10的区别

c# - 解析用户的查询

xml - XSLT value() 和 position() 给出了不正确的索引

javascript - jquery ajax 回复上的 Selecton

java - 使用自定义表单的序列化代理?

javascript - 原型(prototype)中的 JQuery 等价物

java - JAXB:在特殊值的情况下忽略元素序列化(例如 `null` 或 `Double.NaN` )

c# - JavaScript 中的 SHA256Cng

c# - 实时获取进程输出时出错

c# - 反序列化