Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
238 views
in Technique[技术] by (71.8m points)

c# - How do I use the same XMLAttribute for multiple properties?

I have the below wrapper class.

[Serializable]
    public class Vehicle
    {
        public string Make { get; set; }
        public string Model { get; set; }
        public string Year { get; set; }

        public static void Serialize()
        {
            string fileName = "data.xml";
            Console.WriteLine("Enter Make, Model & Year");
            var vehicle = new Vehicle
            {
                Make = "Honda",
                Model = "H1245",
                Year = "1975"
            };
            //Serialization
            var document = new XmlDocument();
            var xml = new XmlSerializer(typeof(Vehicle));
            TextWriter writer = new StreamWriter(fileName);
            xml.Serialize(writer, vehicle);
            writer.Close();
            //Attribution
            if (File.Exists(fileName))
            {
                document.Load(fileName);
                var nodeList = document.SelectNodes("//Vehicle//*");

                var attribute1 = document.CreateAttribute("applicableTo");
                attribute1.Value = "Common";
                var attribute2 = document.CreateAttribute("applicableTo");
                attribute2.Value = "Cfpd";
                var attribute3 = document.CreateAttribute("applicableTo");
                attribute3.Value = "Markel";

                for (int i = 0; i < nodeList.Count; i++)
                {
                    if (nodeList[i].InnerText.Equals("Honda"))
                        ((XmlElement)(nodeList[i])).SetAttributeNode(attribute1);
                    if (nodeList[i].InnerText.Equals("H1245"))
                        ((XmlElement)(nodeList[i])).SetAttributeNode(attribute2);
                    if (nodeList[i].InnerText.Equals("1975"))
                        ((XmlElement)(nodeList[i])).SetAttributeNode(attribute3);
                }
                document.Save(Console.Out);
            }
        }

My desired output is as below. However, I get the same output as XML as below.

<?xml version="1.0" encoding="utf-8"?>
<Vehicle xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Make applicableTo="Common">Honda</Make>
  <Model applicableTo="Cfpd">H1245</Model>
  <Year applicableTo="Markel">1975</Year>
</Vehicle>

Here goes my problem,

How do I have the attribute applicableTo set to Make, Model and Year properties without having to create them like attribute1, attribute2, attribute3 yet values to be assigned based on the input assigned to properties? Which means, if Make is Honda the XML output should be <Make applicableTo="Common">Honda</Make> and likewise.

XMLAttribute can only be set to one property in a class, which is not ideal when dealing with huge number of classes. And so SetAttributeNode throws error -

The 'Attribute' node cannot be inserted because it is already an attribute of another element.

Please help.

Please note that the format of my output shouldn't change.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Using Xml Linq :

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

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:	emp	est.xml";

        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Make", typeof(string));
            dt.Columns.Add("Make Attribute", typeof(string));
            dt.Columns.Add("Model", typeof(string));
            dt.Columns.Add("Model Attribute", typeof(string));
            dt.Columns.Add("Year", typeof(string));
            dt.Columns.Add("Year Attribute", typeof(string));

            dt.Rows.Add(new object[] { "Honda", "Common", "H1245", "Cfpd", "1975", "Markel" });
            dt.Rows.Add(new object[] { "Honda", "Common", "H1245", "Cfpd", "1975", "Markel" });
            dt.Rows.Add(new object[] { "Honda", "Common", "H1245", "Cfpd", "1975", "Markel" });
            Vehicle.Serialize(dt, FILENAME);
        }
    }
    public class Vehicle
    {
        public static void Serialize(DataTable dt, string fileName)
        {
            string ident = 
                "<?xml version="1.0" encoding="utf-8"?>" +
                "<Vehicles xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">" +
                "</Vehicles>";

            XDocument doc = XDocument.Parse(ident);
            XElement xVehicles = doc.Root;

            foreach (DataRow row in dt.AsEnumerable())
            {
                XElement xVehicle = new XElement("Vehicle", new object[] {
                    new XElement("Make", new object[] {new XAttribute("applicableTo", row.Field<string>("Make Attribute")), row.Field<string>("Make")}),
                    new XElement("Make", new object[] {new XAttribute("applicableTo", row.Field<string>("Model Attribute")), row.Field<string>("Model")}),
                    new XElement("Make", new object[] {new XAttribute("applicableTo", row.Field<string>("Year Attribute")), row.Field<string>("Year")})
                });
                xVehicles.Add(xVehicle);
            }
            doc.Save(fileName);
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...