如何为 C# XML 序列化添加属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1012360/
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
How to add attributes for C# XML Serialization
提问by user107779
I am having an issue with serializing and object, I can get it to create all the correct outputs except for where i have an Element that needs a value and an attribute. Here is the required output:
我在序列化和对象方面遇到问题,我可以让它创建所有正确的输出,除了我有一个需要值和属性的元素。这是所需的输出:
<Root>
<Method>Retrieve</Method>
<Options>
<Filter>
<Times>
<TimeFrom>2009-06-17</TimeFrom>
</Times>
<Document type="word">document name</Document>
</Filter>
</Options>
</AdCourierAPI>
I can build all of it but can not find a way to set the Document type attribute, here is a segment of the object class
我可以构建所有这些但找不到设置文档类型属性的方法,这是对象类的一部分
[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;
}
which gives me:
这给了我:
<Document>document name</Document>
rather than:
而不是:
<Document type="word">document name</Document>
but I can not find a way to correct this, please advise.
但我找不到纠正这个问题的方法,请指教。
Thanks
谢谢
采纳答案by bruno conde
Where do you have the type
stored?
你type
储存在哪里?
Normally you could have something like:
通常你可以有这样的东西:
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;
}
回答by Thomas Levesque
The string
class doesn't have a type
property, so you can't use it to create the desired output. You should create a Document
class instead :
该string
班没有一个type
属性,所以你不能用它来创建所需的输出。您应该创建一个Document
类:
public class Document
{
[XmlText]
public string Name;
[XmlAttribute("type")]
public string Type;
}
And you should change the Document
property to type Document
您应该将Document
属性更改为类型Document
回答by Marc Gravell
It sounds like you need an extra class:
听起来您需要额外的课程:
public class Document
{
[XmlAttribute("type")]
public string Type { get; set; }
[XmlText]
public string Name { get; set; }
}
Where an instance (in the example) would have Type = "word"
and Name = "document name"
; documents
would be a List<Document>
.
实例(在示例中)将具有Type = "word"
和的位置Name = "document name"
;documents
将是一个List<Document>
.
By the way - public fields are rarely a good idea...
顺便说一句 - 公共领域很少是一个好主意......
回答by Krzysztof Juszcze
You can use XmlWriter instead XmlSerialization to get this effect. It is more complex but if you have a lot of strings in model it will be cleaner solution.
您可以使用 XmlWriter 代替 XmlSerialization 来获得此效果。它更复杂,但如果模型中有很多字符串,它将是更清晰的解决方案。
Create your own CustomeAttribute, for example:
创建您自己的 CustomeAttribute,例如:
[System.AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class MyCustomAttribute : System.Attribute
{
public MyCustomAttribute (string type)
{
MyType = type;
}
public string MyType { get; set; }
}
Then in model add it, like that:
然后在模型中添加它,就像这样:
public class MyModel
{
[MyCustom("word")]
public string Document { get; set; }
[MyCustom("time")]
public string Time { get; set; }
}
The last part is to create xml with this arguments. You can do it likes that:
最后一部分是使用此参数创建 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
In myXml should be something like that: (values are examples)
在 myXml 中应该是这样的:(值是示例)
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Document MyType="word">something</Document>
<Time MyType="time">11:31:29</Time>
</Root>
You can do it in other way, of course. Here you have some docs which helped me: https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmlwriter?view=netframework-4.8#writing_elements
当然,您可以通过其他方式来实现。这里有一些对我有帮助的文档:https: //docs.microsoft.com/en-us/dotnet/api/system.xml.xmlwriter?view=netframework-4.8# writing_elements