如何为C# XML序列化添加属性

41

我在序列化对象时遇到了问题,除了当我有一个需要值和属性的元素时,我可以得到所有正确的输出。这是所需的输出:

<Root>
  <Method>Retrieve</Method>
  <Options>
    <Filter>
      <Times>
        <TimeFrom>2009-06-17</TimeFrom>
      </Times>
      <Document type="word">document name</Document>
    </Filter>
  </Options>
</AdCourierAPI>

我可以构建所有东西,但找不到设置文档类型属性的方法,这是对象类的一部分:

[XmlRoot("Root"), Serializable]    
public class Root    
{    
    [XmlElement("Method")]    
    public string method="RetrieveApplications";    
    [XmlElement("Options")]    
    public _Options Options;    
}    
public class _Options    
{
    [XmlElement("Filter")]    
    public _Filter Filter;    
}
public class _Filter    
{
    [XmlElement("Times")]    
    public _Times Times;    
    [XmlElement("Documents")]    
    public string Documents;    
}

这给了我:

<Document>document name</Document>

而不是:

<Document type="word">document name</Document>

但我找不到纠正这个问题的方法,请给予建议。

谢谢


抱歉Marc...你一定是在我之前刚好编辑了那个。 - Kev
4个回答

63

你们在哪里储存了type

通常情况下,你可以有类似以下的代码:

class Document {
    [XmlAttribute("type")]
    public string Type { get; set; }
    [XmlText]
    public string Name { get; set; }
}


public class _Filter    
{
    [XmlElement("Times")]    
    public _Times Times;    
    [XmlElement("Document")]    
    public Document Document;    
}

谢谢大家,已解决,非常感谢。 - user107779
哇,这太棒了,本来以为会更复杂。 - Sizons

11

string类没有type属性,因此您无法使用它来创建所需的输出。相反,您应该创建一个Document类:

public class Document
{
    [XmlText]
    public string Name;

    [XmlAttribute("type")]
    public string Type;
}

你需要将Document属性更改为类型Document


我同意(我也正要提交同样的内容!) - Cᴏʀʏ

8

听起来您需要一个额外的类:

public class Document
{
    [XmlAttribute("type")]
    public string Type { get; set; }
    [XmlText]
    public string Name { get; set; }
}

在这个例子中,一个实例将有 Type = "word"Name = "document name"documents 将是一个 List<Document>

顺便说一句 - 公共字段很少是一个好主意...


0

您可以使用XmlWriter而不是XmlSerialization来实现此效果。虽然更复杂,但如果您的模型中有很多字符串,这将是更清晰的解决方案。

创建自己的CustomeAttribute,例如:

[System.AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class MyCustomAttribute : System.Attribute
{
    public MyCustomAttribute (string type)
    {
        MyType = type;
    }
    public string MyType { get; set; }
}

然后在模型中添加它,就像这样:

public class MyModel
{
    [MyCustom("word")]
    public string Document { get; set; }
    [MyCustom("time")]
    public string Time { get; set; }
}

最后一步是使用这些参数创建XML。您可以这样做:
        var doc = new XmlDocument();
        MyModel myModel = new MyModel();//or get it from somewhere else
        using (Stream s = new MemoryStream())
        {
            var settings = new XmlWriterSettings();
            settings.Async = true;
            settings.Indent = true;
            var writer = XmlTextWriter.Create(s, settings);
            await writer.WriteStartDocumentAsync();
            await writer.WriteStartElementAsync(null,"Root", null);

            myModel.GetType().GetProperties().ToList().ForEach(async p =>
            {
                dynamic value = p.GetValue(myModel);
                writer.WriteStartElement(p.Name);
                var myCustomAttribute = p.GetCustomAttributes(typeof(MyCustomAttribute), false).FirstOrDefault() as MyCustomAttribute;
                if(myCustomAttribute != null)
                {
                    await writer.WriteAttributeStringAsync(null, "MyType", null, myCustomAttribute.MyType );
                }

                writer.WriteValue(value);
                await writer.WriteEndElementAsync();
            });

            await writer.WriteEndElementAsync();
            await writer.FlushAsync();
            s.Position = 0;
            doc.Load(s);                
            writer.Close();
        }
        string myXml = doc.OuterXml

在我的 XML 中应该是这样的: (这里只是举例)
<?xml version="1.0" encoding="utf-8"?>
<Root>
    <Document MyType="word">something</Document>
    <Time MyType="time">11:31:29</Time>
</Root>

当然,您也可以用其他方法来实现。这里有一些文档对我很有帮助: https://learn.microsoft.com/en-us/dotnet/api/system.xml.xmlwriter?view=netframework-4.8#writing_elements


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接