2

我需要创建一些带有嵌套属性的 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; }
}
4

6 回答 6

3

尝试改用 XDocument。与 XML 序列化程序相比,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");
于 2013-08-08T17:46:32.733 回答
2

仅仅因为我喜欢用 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>
于 2013-08-09T10:29:07.863 回答
1

XmlElement属性将使您深入一级,如下所示:

[XmlElement(ElementName = "1"]
public string 1 { get; set; }

但这不能满足您的需求,所以...

查看YAXLib:另一个用于 .NET Framework 的 XML 序列化库

它声称拥有support for specifying path-like serialization addresses, e.g., elem1/elem2/elem3, and ../elem1, and ./elem1.

于 2013-08-08T17:39:26.910 回答
0

据我所知,您的选择在这里受到限制:

1) 让您的类结构反映 XML 结构并使用简单的框架注释 - 这是您已经提到的嵌套类成员结构,这是您不喜欢的。

2) 实现 IXmlSerializable 并进行自定义序列化。毕竟,这是自定义序列化。

于 2013-08-08T17:37:49.617 回答
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>
于 2013-08-08T17:46:26.650 回答
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允许您更改元素的名称,以防它需要与属性名称不同。

还有很多其他选择。

于 2017-06-28T15:14:13.700 回答