【问题标题】:Add fixed attribute to XmlElement without a wrapper class在没有包装类的情况下向 XmlElement 添加固定属性
【发布时间】:2017-04-25 07:41:26
【问题描述】:

我有以下示例结构的类:

public class DataClass{

    public String Field1{ get; set; }
    public Int32 Field2{ get; set; }
    public Int32 Field3{ get; set; }

}

我必须为每个字段添加一个固定属性,以便输出看起来像:

<DataClass>
   <Field1 code="code#1">Value of Field1</Field1>
   <Field2 code="code#2">Value of Field2</Field2>
   <Field3 code="code#3">Value of Field3</Field3>
</DataClass>

如果不为每个字段编写包装类,这是否可能? 比如:

public class DataClass{

    [XmlElement(FixedAttribute="code#1")]
    public String Field1{ get; set; }

    [XmlElement(FixedAttribute="code#2")]
    public Int32 Field2{ get; set; }

    [XmlElement(FixedAttribute="code#3")]
    public Int32 Field3{ get; set; }

}

亲切的问候

【问题讨论】:

    标签: c# xml xmlserializer


    【解决方案1】:

    不,XML 属性不提供此类功能。一种选择是让DataClass 实现IXmlSerializable。这使您可以完全控制输出 XML。您必须自己序列化所有属性,但是由于无论如何您都必须为每个属性提供代码属性,所以还不错。如果您有很多 DataClasses,您可能会考虑创建一个自定义属性来装饰属性并将序列化逻辑移动到基类中,或者,如果所有 DataClasses 的公共基类不方便,则将其放入单独的助手类。 IXmlSerializable.WriteXml 然后会调用这个自定义逻辑。如果你控制DataClasses,我认为这是更好的选择。

    一个更hacky的替代方法是为DataClass创建一个包装器,它将包装的DataClass对象的序列化委托给常规XML序列化器,但替换一个自定义XmlWriter,它将您的XML属性添加到XML属性对应的元素。

    【讨论】:

    • 感谢您的解释和提示。我将编写自己的序列化程序。
    【解决方案2】:

    您可以编写自定义序列化程序,而不是使用 Xml Linq 的内置序列化程序

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    namespace ConsoleApplication49
    {
        class Program
        {
    
            static void Main(string[] args)
            {
                XElement dataClass = new XElement("DataClass");
    
                for(int i = 1; i <= 3; i++)
                {
                    XElement field = new XElement("Field" + i.ToString(), new object[] {
                        new XAttribute("code", "code#" + i.ToString()),
                        "Value of Field" + i.ToString()
                    });
                    dataClass.Add(field);
                }
    
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用自定义 xml 编写器:

      public class DataClassWriter : XmlTextWriter
      {
          public DataClassWriter(string url) : base(url, Encoding.UTF8) { }
      
          public override void WriteStartElement(string prefix, string localName, string ns)
          {
              if (localName.StartsWith("Field"))
              {
                  base.WriteStartElement(prefix, localName, ns);
                  base.WriteAttributeString("code", "code#" + localName.Substring(5));
              }
              else
                  base.WriteStartElement(prefix, localName, ns);
          }
      }
      

      使用:

      var xs = new XmlSerializer(typeof(DataClass));
      
      using (var writer = new DataClassWriter("out.xml"))
          xs.Serialize(writer, data);
      

      【讨论】:

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