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 を使用しようとしています。XDocuments は、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属性は、次のように 1 レベルの深さになります。

[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ます。

于 2013-08-08T17:39:26.910 に答える
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

私が知る限り、あなたの選択肢はここに限られています:

1) クラス構造に XML 構造を反映させ、単純なフレームワーク アノテーションを使用します。これは、既に嫌悪感を示したネストされたクラス メンバー構造です。

2) IXmlSerializable を実装し、カスタムのシリアル化を行います。結局のところ、これはカスタムのシリアル化です。

于 2013-08-08T17:37:49.617 に答える
0

Karls answer のおかげで、私はこれを行うために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 に答える