我有一个问题,也许可以用比我目前的解决方案更有效或更干净的方式来解决。
在过去的几天里,我对如何通过属性控制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”。
抱歉,我的帖子太长了,但我觉得最好有一些合适的代码示例,如果你需要更多的信息,请说。