C# 将属性序列化为元素中的 Xml 属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11330643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 17:27:51  来源:igfitidea点击:

Serialize Property as Xml Attribute in Element

c#.netxmlxml-serialization

提问by IUnknown

I have the following class:

我有以下课程:

[Serializable]
public class SomeModel
{
    [XmlElement("SomeStringElementName")]
    public string SomeString { get; set; }

    [XmlElement("SomeInfoElementName")]
    public int SomeInfo { get; set; }
}

Which (when populated with some test data) and Serialized using XmlSerializer.Serialize() results in the following XML:

其中(使用一些测试数据填充时)并使用 XmlSerializer.Serialize() 进行序列化会产生以下 XML:

<SomeModel>
  <SomeStringElementName>testData</SomeStringElementName>
  <SomeInfoElementName>5</SomeInfoElementName>
</SomeModel>

What I need to have is:

我需要的是:

<SomeModel>
  <SomeStringElementName Value="testData" />
  <SomeInfoElementName Value="5" />
</SomeModel>

Is there a way to specify this as attributes without writing my own custom serialization code?

有没有办法在不编写自己的自定义序列化代码的情况下将其指定为属性?

采纳答案by Darin Dimitrov

You will need wrapper classes:

您将需要包装类:

public class SomeIntInfo
{
    [XmlAttribute]
    public int Value { get; set; }
}

public class SomeStringInfo
{
    [XmlAttribute]
    public string Value { get; set; }
}

public class SomeModel
{
    [XmlElement("SomeStringElementName")]
    public SomeStringInfo SomeString { get; set; }

    [XmlElement("SomeInfoElementName")]
    public SomeIntInfo SomeInfo { get; set; }
}

or a more generic approach if you prefer:

如果您愿意,或者更通用的方法:

public class SomeInfo<T>
{
    [XmlAttribute]
    public T Value { get; set; }
}

public class SomeModel
{
    [XmlElement("SomeStringElementName")]
    public SomeInfo<string> SomeString { get; set; }

    [XmlElement("SomeInfoElementName")]
    public SomeInfo<int> SomeInfo { get; set; }
}

And then:

进而:

class Program
{
    static void Main()
    {
        var model = new SomeModel
        {
            SomeString = new SomeInfo<string> { Value = "testData" },
            SomeInfo = new SomeInfo<int> { Value = 5 }
        };
        var serializer = new XmlSerializer(model.GetType());
        serializer.Serialize(Console.Out, model);
    }
}

will produce:

将产生:

<?xml version="1.0" encoding="ibm850"?>
<SomeModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <SomeStringElementName Value="testData" />
  <SomeInfoElementName Value="5" />
</SomeModel>

回答by Chris Gessler

Kind of, use the XmlAttributeinstead of XmlElement, but it won't look like what you want. It will look like the following:

有点,使用XmlAttribute代替XmlElement,但它看起来不像你想要的。它将如下所示:

<SomeModel SomeStringElementName="testData"> 
</SomeModel> 

The only way I can think of to achieve what you want (natively) would be to have properties pointing to objects named SomeStringElementName and SomeInfoElementName where the class contained a single getter named "value". You could take this one step further and use DataContractSerializer so that the wrapper classes can be private. XmlSerializer won't read private properties.

我能想到的实现您想要的(本机)的唯一方法是让属性指向名为 SomeStringElementName 和 SomeInfoElementName 的对象,其中该类包含一个名为“value”的 getter。您可以更进一步并使用 DataContractSerializer 以便包装类可以是私有的。XmlSerializer 不会读取私有属性。

// TODO: make the class generic so that an int or string can be used.
[Serializable]  
public class SerializationClass
{
    public SerializationClass(string value)
    {
        this.Value = value;
    }

    [XmlAttribute("value")]
    public string Value { get; }
}


[Serializable]                     
public class SomeModel                     
{                     
    [XmlIgnore]                     
    public string SomeString { get; set; }                     

    [XmlIgnore]                      
    public int SomeInfo { get; set; }  

    [XmlElement]
    public SerializationClass SomeStringElementName
    {
        get { return new SerializationClass(this.SomeString); }
    }               
}