我需要使用嵌套属性创建一些XML,看起来与此类似:
<1>
<1a>
Some stuff
</1a>
<1b>
Some stuff
<1c>
Some stuff
</1c>
</1b>
</1>
通常,为了创建嵌套元素,对象内部嵌套了类。但是我需要创建的XML会导致一个内部有20多个嵌套类的对象,这对我来说太可怕了。没有重复这些元素,因此我认为不需要创建所有这些类。
有没有办法告诉XML序列化程序嵌套元素?例如,对类中的属性如下:
public class XMLExport
{
[DataMember(Order = 0, Name = "1")]
public string 1 { get; set; }
[DataMember(Order = 1, Name = "1/1a")]
public string 1a { get; set; }
[DataMember(Order = 2, Name = "1/1b")]
public string 1b { get; set; }
[DataMember(Order = 3, Name = "1/1b/1c")]
public string 1c { get; set; }
}
答案 0 :(得分:3)
尝试使用XDocument。与XML Serializer相比,XDocuments非常精彩且易于使用。关于它的MSDN文档非常棒。 http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.aspx
使用他们的示例,您可以像这样创建示例xml文件:
XDocument srcTree = new XDocument(
new XComment("This is a comment"),
new XElement("1",
new XElement("1a", "Some Stuff"),
new XElement("1b",
new XElement("1c", "Some Stuff"
)
)
);
然后保存它
srcTree.save("path\to\file");
答案 1 :(得分:1)
XmlElement
属性会让你达到一个深度,如下所示:
[XmlElement(ElementName = "1"]
public string 1 { get; set; }
但这不符合您的需求,所以......
查看YAXLib: Yet Another XML Serialization Library for the .NET Framework。
声称拥有support for specifying path-like serialization addresses, e.g., elem1/elem2/elem3, and ../elem1, and ./elem1
。
答案 2 :(得分:1)
仅仅因为我喜欢用LINQ做事,这里有另一种选择:
假设您有类似这样的类:
public class lClass
{
public string la{get;set;}
public string lb{get;set;}
public string lc{get;set;}
}
你有这个班级的名单:
List<lClass> l = new List<lClass>();
l.Add(new lClass{la ="1 Some Stuff a",lb ="1 Some Stuff b",lc = "1 Some Stuff c"});
l.Add(new lClass{la ="2 Some Stuff a",lb ="2 Some Stuff b",lc = "2 Some Stuff c"});
l.Add(new lClass{la ="3 Some Stuff a",lb ="3 Some Stuff b",lc = "3 Some Stuff c"});
l.Add(new lClass{la ="4 Some Stuff a",lb ="4 Some Stuff b",lc = "4 Some Stuff c"});
使用以下代码:
XElement xe = new XElement("root");
xe.Add
(
l.Select
(
x =>
new XElement
(
"l",
new XElement
(
"la",
x.la
),
new XElement
(
"lb",
x.lb,
new XElement
(
"lc",
x.lc
)
)
)
)
);
你得到:
<root>
<l>
<la>1 Some Stuff a</la>
<lb>1 Some Stuff b<lc>1 Some Stuff c</lc></lb>
</l>
<l>
<la>2 Some Stuff a</la>
<lb>2 Some Stuff b<lc>2 Some Stuff c</lc></lb>
</l>
<l>
<la>3 Some Stuff a</la>
<lb>3 Some Stuff b<lc>3 Some Stuff c</lc></lb>
</l>
<l>
<la>4 Some Stuff a</la>
<lb>4 Some Stuff b<lc>4 Some Stuff c</lc></lb>
</l>
</root>
答案 3 :(得分:0)
据我所知,您的选择仅限于此:
1)让您的类结构反映XML结构并使用简单的框架注释 - 这是您已经提到过的厌恶的嵌套类成员结构。
2)实现IXmlSerializable并执行自定义序列化。毕竟,这是自定义序列化。
答案 4 :(得分:0)
你可以尝试一个带有自引用的类,比如下面的文字:
public class Item
{
public string Value { get; set; }
public Item[] ChildList { get; set; }
}
然后您将拥有以下内容:
var obj = new Item
{
Value = "Something",
ChildList = new[]
{
new Item
{
Value = "Something",
ChildList = new[]
{
new Item
{
Value = "Something",
ChildList = new[] { new Item() {Value = "End"} }
}
}
}
}
};
var serializer = new XmlSerializer(typeof(Item));
using (var writer = new StringWriter())
{
serializer.Serialize(writer, obj);
Console.WriteLine(writer.ToString());
Console.Read();
}
输出:
<?xml version="1.0" encoding="utf-16"?>
<Item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Value>Something</Value>
<ChildList>
<Item>
<Value>Something</Value>
<ChildList>
<Item>
<Value>Something</Value>
<ChildList>
<Item>
<Value>End</Value>
</Item>
</ChildList>
</Item>
</ChildList>
</Item>
</ChildList>
</Item>
答案 5 :(得分:0)
感谢Karls的回答,我使用了YAXLib来做这件事,它提供了很好的,干净的类,如下所示:
public class XMLExport
{
[YAXElementFor("")]
[YAXSerializeAs("1")]
public string 1 { get; set; }
[YAXElementFor("1")]
[YAXSerializeAs("1a")]
public string 1a { get; set; }
[YAXElementFor("1")]
[YAXSerializeAs("1b")]
public string 1b { get; set; }
[YAXElementFor("1/1a/1b")]
[YAXSerializeAs("1c")]
public string 1c { get; set; }
}
YAXElementFor
允许您放置一个路径,以便您可以嵌套元素。
YAXSerializeAs
允许您更改元素的名称,以防它需要与属性名称不同。
还有其他一些选择。