代码之家  ›  专栏  ›  技术社区  ›  reSPAWNed

C#-Xml序列化不明确的复杂类型

  •  1
  • reSPAWNed  · 技术社区  · 14 年前

    我有一个问题,也许可以用比我目前的解决方案更有效或更干净的方式来解决。

    在过去的几天里,我对如何通过属性控制Xml序列化有了相当好的理解,但是Xml结构的一部分非常模糊,以至于我无法找到一个聪明的解决方案。

    我得到了一个Xml模式,它不能更改,我必须为它创建一个C#类。

    困扰我的代码如下:

    <xs:complexType name="dataRefType">
        <xs:sequence>
            <xs:element name="Data" type="DataType"/>
            <xs:sequence minOccurs="0" maxOccurs="unbounded">
                <xs:element name="Separator" type="xs:string"/>
                <xs:element name="Data" type="DataType"/>
            </xs:sequence>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="DataType">
        <xs:choice>
            <xs:sequence>
                <xs:element name="DataOwner" type="xs:string"/>
                <xs:element name="Name" type="xs:string"/>
            </xs:sequence>
            <xs:element name="XPath" type="xs:string"/>
        </xs:choice>
    </xs:complexType>
    

    我的第一个想法是通过一个泛型列表来管理这个问题,这个列表可以是三种类型的类中的一种,到目前为止,它已经工作了,但是这里的问题是“Data”这个模棱两可的名称。

    以下是我最初编写的代码:

    [XmlRoot("DataRef")]
    public class DataRef
    {
        protected List<DataRoot> m_Data = new List<DataRoot>(1);
    
        [XmlElement(typeof(DataUserField))]
        [XmlElement(typeof(DataMasterField))]
        [XmlElement(typeof(DataSeparator))]
        public List<DataRoot> Data { get { return m_Data; } set { m_Data = value; } }
    }
    
    public abstract class DataRoot { }
    
    [XmlRoot("Data")]
    public class DataUserField : DataRoot
    {
        protected string m_DataOwner;
        protected string m_Name;
    
        [XmlElement("DataOwner")]
        public string DataOwner { get { return m_DataOwner; } set { m_DataOwner = value; } }
        [XmlElement("Name")]
        public string Name { get { return m_Name; } set { m_Name = value; } }
    }
    
    [XmlRoot("Data")]
    public class DataMasterField : DataRoot
    {
        protected string m_XPath;
    
        [XmlElement("XPath")]
        public string XPath { get { return m_XPath; } set { m_XPath = value; } }
    }
    
    [XmlRoot("Separator")]
    public class DataSeparator : DataRoot
    {
        protected string m_Text = "";
    
        [XmlText()]
        public string Text { get { return m_Text; } set { m_Text = value; } }
    }
    

    不幸的是,这没有起作用,我假设这是因为元素名“Data”不明确,因为错误消息非常模糊,但确实有一个错误行号的引用。

    正如我在一开始所说的,我已经有了一个解决方案,但它远不是优雅的,而且绝对不符合.Net精神,这就是为什么我非常感谢任何帮助。

    我的解决方案涉及一个类来表示“DataType”,其中一个字段表示类型,另外三个字段表示“DataOwner”、“Name”和“XPath”,其中类型是一个枚举,可以是“DataUserField”或“DataMasterField”。

    抱歉,我的帖子太长了,但我觉得最好有一些合适的代码示例,如果你需要更多的信息,请说。

    1 回复  |  直到 14 年前
        1
  •  0
  •   Patrick McDonald    14 年前

    看一看这个XSD.EXE文件工具,它将从XSD模式为您生成C类。

    它应该已经安装在您的计算机上(C:\Program Files\Microsoft SDK\Windows\v6.0A\bin)\xsd.exe文件对于.NET Framework 3.5)。

    有一个教程可以使用它 codeproject.com