简体   繁体   中英

How to serialize property name and property value as attribute value

My class looks like

public class Test
{
    private string name;        
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    private int age;        
    public int Age
    {
        get { return age; }
        set { age = value; }
    }        
}

I want the xml result like:

<NodeList>
<Node>
    <DataNode Key="Name" Value="Tom" />
    <DataNode Key="Age" Value="30" />
</Node>
<Node>
    <DataNode Key="Name" Value="John" />
    <DataNode Key="Age" Value="35" />
</Node>
</NodeList>

I have tried to set XmlAttribute in the property, but the result is not what I want. Any suggestions?

Update: This is what I get:

 <?xml version="1.0" encoding="utf-16"?><Node xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Name="Allen" Age="28" /> 

I recommend you to use much straightforward approach for your data like this:

[Serializable()]
public class NodeList {
    [XmlArray("Node")]
    [XmlArrayItem("DataNode")]
    public Test[] Nodes;
}

public class Test {
    [XmlAttribute]
    public string Name { get; set; }
    public int Age { get; set; }
}

And use it like this:

string folderpath = Application.StartupPath + "\\settings";
string appSettingsFilename = "testsettings2";
if (!Directory.Exists(folderpath))
    Directory.CreateDirectory(folderpath);
string filepath = folderpath + "\\" + appSettingsFilename + ".xml";

NodeList nodes = new NodeList();
XmlSerializer serializer = new XmlSerializer(typeof(NodeList));
TextWriter configWriteFileStream = new StreamWriter(filepath);

nodes.Nodes = new Test[2] {
    new Test() { Name = "Tom", Age=30},
    new Test() { Name = "John", Age=35}
};

serializer.Serialize(configWriteFileStream, nodes);
configWriteFileStream.Close();

And you shall get:

<?xml version="1.0" encoding="utf-8"?>
<NodeList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Node>
    <DataNode Name="Tom" Age="30" />
    <DataNode Name="John" Age="35" />
  </Node>
</NodeList>

That being said, to get XML file as you want, you should actually declare your classes like this (commented):

[Serializable()]
public class DummyClass2 {
    [XmlElement("NodeList")] //necessary to indicate that this is an element, otherwise will be considered as array
    public TestList[] NodeList = null;
}

public class TestList {
    [XmlArray("Node")] //let this be array
    [XmlArrayItem("DataNode")]
    public Test[] TestItem { get; set; }
}

public class Test {
    private string key;
    [XmlAttribute("Key")]
    public string Key { //declare as Key instead
        get { return key; }
        set { key = value; }
    }

    private string value2; //cannot be int, must be string to accommodate both "Tom" and "30"
    [XmlAttribute("Value")]
    public string Value {  //declare as Value instead
        get { return value2; }
        set { value2 = value; }
    }
}

And you use it like this:

string folderpath = Application.StartupPath + "\\settings";
string appSettingsFilename = "testsettings";
if (!Directory.Exists(folderpath))
    Directory.CreateDirectory(folderpath);
string filepath = folderpath + "\\" + appSettingsFilename + ".xml";

DummyClass2 dummyClass2 = new DummyClass2();
XmlSerializer serializer = new XmlSerializer(typeof(DummyClass2));
TextWriter configWriteFileStream = new StreamWriter(filepath);

dummyClass2.NodeList =  new TestList[2] {
    new TestList() {
        TestItem = new Test[2] { 
            new Test() { Key="Name", Value="Tom"},
            new Test() { Key="Age", Value="30"}
        }
    },
    new TestList() {
        TestItem = new Test[2] { 
            new Test() { Key="Name", Value="John"},
            new Test() { Key="Age", Value="35"}
        }
    }
};

serializer.Serialize(configWriteFileStream, dummyClass2);
configWriteFileStream.Close();

And you should get:

<?xml version="1.0" encoding="utf-8"?>
<DummyClass2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <NodeList>
    <Node>
      <DataNode Key="Name" Value="Tom" />
      <DataNode Key="Age" Value="30" />
    </Node>
  </NodeList>
  <NodeList>
    <Node>
      <DataNode Key="Name" Value="John" />
      <DataNode Key="Age" Value="35" />
    </Node>
  </NodeList>
</DummyClass2>

You don't need serialize. Try this

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;



namespace ConsoleApplication85
{
    class Program
    {
        static void Main(string[] args)
        {
            var inputs = new[]  {
                new { name = "Tom", age = 30},
                new { name = "John", age = 35}
                           };


            XElement nodeList = new XElement("NodeList");
            XElement node = new XElement("Node");
            nodeList.Add(node);

            foreach (var input in inputs)
            {
                node.Add(new XElement("DataNode", new XAttribute[] { new XAttribute("Key", input.name), new XAttribute("Value", input.age)}));
            }
        }

    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM