使用c#&;实现XML序列化;windows窗体
我正在尝试使用windows窗体创建一个航路点生成器,它允许用户通过GUI创建航路点和路径数据,并将数据输出到XML文件。我选择利用内置的c#XML序列化功能,但无法按照客户机要求的方式格式化XML输出 航路点数据对象的剥离版本如下所示:使用c#&;实现XML序列化;windows窗体,c#,xml,serialization,C#,Xml,Serialization,我正在尝试使用windows窗体创建一个航路点生成器,它允许用户通过GUI创建航路点和路径数据,并将数据输出到XML文件。我选择利用内置的c#XML序列化功能,但无法按照客户机要求的方式格式化XML输出 航路点数据对象的剥离版本如下所示: // Waypoint data class [XmlRoot("RootNode")] public class WaypointProjectData { [XmlElement("Map")] // Also tried t
// Waypoint data class
[XmlRoot("RootNode")]
public class WaypointProjectData
{
[XmlElement("Map")] // Also tried to use XmlElementAttribute,
[XmlAttribute("file")] // XmlAttributeAttribute, and many variations
// of these qualifiers, with no success
public string m_szMapImageFileName;
[XmlAttribute("width")]
public int m_iWidth;
[XmlAttribute("height")]
public int m_iHeight;
[XmlArray("Nodes")]
public ArrayList m_aoNodes;
WaypointProjectData()
{
m_szMapImageFileName = "map.png";
m_aoNodes = new ArrayList();
}
}
客户端要求XML输出符合以下布局/格式:
<RootNode>
<Map file="map.png" width="100" height="100" />
<OtherData var="variable" data="10" />
<Nodes>
<Node x="10" y="30" />
<Node x="30" y="20" /> // etc...
</Nodes>
</RootNode>
//等等。。。
一些关于如何使用c#xml序列化的清晰示例将非常有用。谢谢 一旦你脱离常规,连续剧就是一个巨大的项目。 您需要一些东西标记为map,可能还有其他数据,这意味着您需要一个与节点对应的类或结构。 e、 g.WaypointProejctdata作为类映射,具有文件名、宽度和高度属性。 我的一般经验法则是,只要我必须开始处理我的对象以获取xml,序列化就会被装箱,我添加了一个接口,该接口使用XmlReader或Writer并实现它。
试着让序列化来做你想做的事情通常比那样做更多的代码,更不容易理解。当我必须以这样一种特定的Xml格式序列化某些东西时,我从一个模式开始(如果必要,可以推断,如果知道,可以手工制作)。然后,我使用VS xsd工具创建序列化类(是的,我知道xsd可以用于推断模式部分——我只是从来没有为此而费心) 因此,如果您有一个根据示例创建的xsd文件(请注意,我尽可能多地指定了数据类型,这有助于xsd工具为属性使用适当的类型):
如果将其命名为Root.xsd,则可以转到VS命令行并运行
xsd Root.xsd/c/n:myProject.Xml
这将创建一个类文件(名为Root.cs,因为这是处理Root.xsd时的默认值),其中包含可以轻松插入.Net以序列化和反序列化XML的对象。注意,我指定了类将具有的名称空间(“/n:myProject.Xml”)。我更喜欢控制该名称空间,但对于其他名称空间,默认值通常是可以接受的。此外,该工具还创建了分部类,因此如果需要自定义属性访问器,可以将它们添加到单独的文件中,如果需要再次运行该工具,该文件将不会被删除
另一个技巧是,我在项目中创建一个名为“xsd Command Line.txt”的文本文件。这样,我只需将其粘贴到VS命令行中,而不必记住我使用的所有其他内容。可以在给定属性上使用XmlElement或XmlAttribute节点,但不能同时使用这两个节点。可能需要为每个XmlNode创建一个对象,映射到该元素的属性,然后自己合并XML结果?在注释[XmlElement(“map”)]时,文件字符串、宽度和高度数据都作为根节点的属性添加。或者,当注释掉[XmlAttribute(“文件”)]时,文件字符串放在根节点之后的元素标记中,但是宽度和高度仍然作为根节点的属性放置。是的,Eric,您是正确的。我可能应该指出,我在上面的代码中留下它们只是为了表明我已经尝试了它们,而不是它们打算一起工作。此外,每个节点都被创建为对象,这些对象通过上述对象中的函数添加到arraylist中,我在上述代码中没有包含这些函数。虽然我最终也会希望序列化节点,但我遇到的主要问题是,我不确定如何将上述数据序列化为自定义命名元素中的自定义命名属性。我感谢做出此响应所做的努力,但它确实没有回答我的问题。为了使航路点生成器的文件输出与客户端软件兼容,必须遵循特定的布局。上面的示例不仅与该格式有很大差异,而且还缺少我所要求的:用于创建输出的c#实现示例。不过感谢您的回复。将该模式复制到xsd中并运行VS xsd工具,您将得到您想要的:即用于创建输出的c#实现示例。我觉得这很清楚。我没有包含实际的自动生成代码,因为我认为您可能希望自己对其进行调整,以实现真正想要的结果。毕竟,没有人真正想要一个名为“OtherData”的节点,它的属性是“var”和“data”…哦,糟糕。我误解了你的帖子,意思是我用一种(模式)格式输出生成器,然后通过另一个(部分)程序将该文件转换为所需格式,这似乎是获得最终结果的一种迂回方式。谢谢你的澄清。我将浏览一下VSXSD/schema工具,看看我能想出什么。当您必须处理Xml序列化时,它是一个非常有用的工具。
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="RootNode">
<xs:complexType>
<xs:sequence>
<xs:element name="Map">
<xs:complexType>
<xs:attribute name="file" type="xs:string"/>
<xs:attribute name="width" type="xs:decimal"/>
<xs:attribute name="height" type="xs:decimal"/>
</xs:complexType>
</xs:element>
<xs:element name="OtherData">
<xs:complexType>
<xs:attribute name="var" type="xs:string"/>
<xs:attribute name="data" type="xs:decimal"/>
</xs:complexType>
</xs:element>
<xs:element name="Nodes" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="Node" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="x" type="xs:decimal"/>
<xs:attribute name="y" type="xs:decimal"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>