生成 XML 文件并读回

Generate XML file and read it back

我正在寻找一种干净利落的方式来将 XML 写入配置文件并能够将其读回应用程序。

我有一个属性数组,每个属性都包含一个字段列表。

例如相机属性列表。

每个属性有 名称、值、类别、类型、说明。

我希望我的 XML 配置看起来像这样

<Camera_Properties>
    <Property Name="Height" Value="40" Category="Dimensions" Type="Int" Description="The height of the box">
    <Property Name="Width" Value="40" Category="Dimensions" Type="Int" Description="The width of the box">
</Camera_Properties>

首先,这可能吗,或者实用吗?

我似乎找不到写这个的方法,更无能为力的是能够以这样一种方式解析它,它可以被拉开,这样我就可以读取配置文件,并在找到每个元素时调用代码像这样

SetProperty(xmlelement.name, xmlelement.Value, xmlelement.Type);

到目前为止我已经设法得到这个输出

<Camera_Properties>
    <Property>
        <Name> Height</Name>
        <Value> 100 </Value>
        <Category> Dimensions </Category>
        <Type> Int </Type>
        <Description> Height of the box </Description>
    </Property>
 </Camera_Properties>

但这对于我需要如何使用配置文件来说并不实用。

我用 System.Xml.XmlDocument 走到了这一步。如果有更好的选择,我将不胜感激。

但是由于有数百个属性,这太乱了,难以阅读。

如果有人可以提供帮助或知道哪里可能有相关示例,我可以将其用作指南,那将大有帮助。

谢谢

编辑

我想遍历并生成一个 XML 文件,其中包含数组中的这些属性。这个想法是,这个文件可以用来加载属性并将属性设置为每次硬件断电时的变化。

public void CreateXML()
{
   // Setup document and header tags

    foreach(Property prop in propertyArray)
    {
       create single element here with prop.Name, Prop.Age etc as attributes
    }

    SaveXml(Filename);
}

我用于硬件的 SDK 有一个参数数组,所以我更愿意从中生成文件而不是数据集。

看起来您正在添加节点,而不是添加一个带有属性的节点。

尝试添加一个名为 Properties 的节点,然后将该节点上的属性设置为您想要的 key/values。

举个例子: Microsoft XML Attributes Documentation

我在工作中使用序列化做了很多工作。

XmlSerializer

您可以创建一些 类 来存储信息。写入对象属性,然后使用以下内容对其进行序列化:

XmlSerializer xsSubmit = new XmlSerializer(typeof(Claim));

            var subReq = Claim;
            using (StringWriter sww = new Utf8StringWriter())
            {
                XmlWriterSettings xmlWriterSettings = new XmlWriterSettings
                {
                    Indent = true,
                    OmitXmlDeclaration = false,
                    Encoding = Encoding.Unicode
                };

                using (XmlWriter writer = XmlWriter.Create(sww, xmlWriterSettings))
                {
                    xsSubmit.Serialize(writer, subReq);
                    var xml = sww.ToString();
                    PrintOutput(xml);


                    File.WriteAllText("out.xml", text);

                    Console.WriteLine(xml);
                }
            }

这是我的工作示例。请注意第一行我有 typeof(Claim) Claim 是我的父对象,其中包含我的子对象。

将嵌套在另一个对象中的每个对象视为 XML 的每个嵌套:

 public class Claim
    {
        public Accident Accident { get; set; }

        public Driver Driver { get; set; }

        public Insurer Insurer { get; set; }

        public Owner Owner { get; set; }

        public Policy Policy { get; set; }

        public Solicitor Solicitor { get; set; }

        public Source Source { get; set; }

}

你可以在这里看到我上周关于类似问题的问题:

数据集序列化

DataSet ds = new Dataset();
DataTable dt = new DataTable();
ds.Tables.Add(dt);
System.IO.StringWriter writer = new System.IO.StringWriter();
Case.WriteXml(writer, XmlWriteMode.WriteSchema);

如果您坚持使用属性,请参阅此处:Serialize Property as Xml Attribute in Element

编辑: 您可以使用这两种方法重新阅读它们。您可以使用 XMLSerializer 将数据读回对象,也可以反序列化数据集。

您可以使用 XmlSerializer to automatically serialize and deserialize your property collection. If you do, you must mark your properties with the [XmlAttribute] 属性通知序列化器它们将被序列化为 XML 属性。

例如,给定 类:

public class Property
{
    [XmlAttribute]
    public string Name { get; set; }
    [XmlAttribute]
    public string Value { get; set; }
    [XmlAttribute]
    public string Category { get; set; }
    [XmlAttribute]
    public string Type { get; set; }
    [XmlAttribute]
    public string Description { get; set; }
}

[XmlRoot("Camera_Properties")]
public class CameraPropertyList
{
    [XmlElement("Property")]
    public List<Property> Properties { get; set; }
}

您可以按如下方式测试读写:

        string xml = @"<Camera_Properties>
            <Property Name=""Height"" Value=""40"" Category=""Dimensions"" Type=""Int"" Description=""The height of the box""/>
            <Property Name=""Width"" Value=""40"" Category=""Dimensions"" Type=""Int"" Description=""The width of the box""/>
        </Camera_Properties>
        ";
        CameraPropertyList properties;
        using (StringReader reader = new StringReader(xml))
        {
            properties = (CameraPropertyList)(new XmlSerializer(typeof(CameraPropertyList))).Deserialize(reader);
        }

        string xmlOut;
        using (var textWriter = new StringWriter())
        {
            var settings = new XmlWriterSettings() { Indent = true, IndentChars = "    " }; // For cosmetic purposes.
            using (var xmlWriter = XmlWriter.Create(textWriter, settings))
                (new XmlSerializer(typeof(CameraPropertyList))).Serialize(xmlWriter, properties);
            xmlOut = textWriter.ToString();
        }

        Debug.WriteLine(xmlOut);

生成的 XML 输出如下所示:

<Camera_Properties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Property Name="Height" Value="40" Category="Dimensions" Type="Int" Description="The height of the box" />
    <Property Name="Width" Value="40" Category="Dimensions" Type="Int" Description="The width of the box" />
</Camera_Properties>

如果出于某种原因,你想取消标准 xsixsd 命名空间,你可以这样做:

        using (var textWriter = new StringWriter())
        {
            var settings = new XmlWriterSettings() { Indent = true, IndentChars = "    " }; // For cosmetic purposes.
            var ns = new XmlSerializerNamespaces();
            ns.Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines.
            using (var xmlWriter = XmlWriter.Create(textWriter, settings))
                (new XmlSerializer(typeof(CameraPropertyList))).Serialize(xmlWriter, properties, ns);
            xmlOut = textWriter.ToString();
        }

或者,如果您更喜欢通过创建 XmlDocument 来手动执行此操作,您可以执行以下操作:

    XmlDocument ToXmlDocument(CameraPropertyList list)
    {
        var doc = new XmlDocument();
        var rootNode = doc.CreateElement("Camera_Properties");
        doc.AppendChild(rootNode);

        foreach (var property in list.Properties)
        {
            var element = doc.CreateElement("Property");
            element.SetAttribute("Name", property.Name);
            element.SetAttribute("Value", property.Value);
            element.SetAttribute("Category", property.Category);
            element.SetAttribute("Type", property.Type);
            element.SetAttribute("Description", property.Description);
            rootNode.AppendChild(element);
        }

        return doc;
    }