【问题标题】:How do I use the same XMLAttribute for multiple properties?如何为多个属性使用相同的 XMLAttribute?
【发布时间】:2020-10-19 21:45:27
【问题描述】:

我有下面的包装类。

[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);
            }
        }

我想要的输出如下。但是,我得到与 XML 相同的输出,如下所示。

<?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>

这是我的问题,

如何将属性 applicableTo 设置为 Make、Model 和 Year 属性,而不必像 attribute1attribute2attribute3 那样创建它们,但要根据分配给属性的输入分配值?这意味着,如果 MakeHonda,则 XML 输出应该是 &lt;Make applicableTo="Common"&gt;Honda&lt;/Make&gt; 并且同样如此。

XMLAttribute 只能设置为一个类中的一个属性,这在处理大量类时并不理想。所以SetAttributeNode 抛出错误 -

“属性”节点无法插入,因为它已经是另一个元素的属性。

请帮忙。

请注意,我的输出格式不应更改。

【问题讨论】:

  • 我想要的输出如下。但是,我得到与 XML 相同的输出,如下所示。 -- 什么?你得到你想要的输出了吗?
  • 今天好像又问了一个eerily similar question。家庭作业可能吗?完全披露:我给了这个问题一个答案。但是现在,当结合如何提出这两个问题时,我无法弄清楚我的回答是否有帮助。 :(
  • 感谢@SeanSkelly 在链接中的回答,这很有帮助。尽管我尝试的其他解决方案是为每个属性创建多个类,但它被面试官拒绝了,因为如果有超过 100 个属性,它就没有用了。所以我想出了我在 OP 中的内容,但我还不知道它是否被接受。当我不得不使用 XmlSerializer 时,您在链接中的回答是完美的。在我的采访中提出的问题很模糊,我没有被告知属性值是静态的还是根据用户输入分配的。再次感谢。
  • @dbc 我有所需的输出,我想知道是否有其他方法可以实现这一点,我对 C# 和 stackoverflow 真的很陌生,所以如果我很粗鲁,我很抱歉。 :(

标签: c# xml


【解决方案1】:

使用 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:\temp\test.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);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多