私はいくつかの非常に単純なコードを持っています。
//File Company.cs
using System;
using Sharpen;
using System.Reflection;
using System.Runtime.Serialization;
namespace XPathTest
{
[DataContract(IsReference=true)]
public class Company
{
[DataMember]
public AList<Person> employees {get; set;}
public Company ()
{
employees = new AList<Person>();
}
}
}
//File Employee.cs
using System;
using System.Reflection;
using System.Runtime.Serialization;
namespace XPathTest
{
[DataContract(IsReference=true)]
public class Employee : Person
{
public Employee ()
{
}
}
}
//File Manager.cs
using System;
using Sharpen;
using System.Reflection;
using System.Runtime.Serialization;
namespace XPathTest
{
[DataContract(IsReference=true)]
public class Manager : Person
{
[DataMember(EmitDefaultValue=false)]
public AList<Person> employees { get; set; }
public Manager ()
{
employees = new AList<Person>();
}
public void AddEmployee(Person employee)
{
employees.Add (employee);
}
}
}
//File Person.cs
using System;
using System.Reflection;
using System.Runtime.Serialization;
namespace XPathTest
{
[DataContract(IsReference=true)]
public class Person
{
[DataMember]
public int SSNum { get; set; }
[DataMember]
public string name { get; set; }
[DataMember(EmitDefaultValue=false)]
public Person manager {get; set;}
public Person ()
{
}
public void SetManager(Person manager)
{
this.manager = manager;
}
}
}
//File Main.cs
using System;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.XPath;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using XPathTest;
public class Test
{
public static void Main()
{
// Read and write purchase orders.
Test t = new Test();
t.MarshalCompany ("po.xml");
}
public Company BuildCompany ()
{
Company company = new Company();
Manager employee1 = new Manager();
employee1.SSNum = 1337;
employee1.name ="Jane Doe";
company.employees.Add(employee1);
Employee employee2 = new Employee();
employee2.SSNum = 8008132;
employee2.name = "John Smith";
employee2.SetManager(employee1);
company.employees.Add(employee2);
Employee employee3 = new Employee();
employee3.SSNum = 1138;
employee3.name = "Anne Jones";
employee3.SetManager(employee1);
company.employees.Add(employee3);
employee1.AddEmployee(employee2);
employee1.AddEmployee(employee3);
Manager manager1 = new Manager();
manager1.SSNum = 314;
manager1.name = "Boss Hog";
//manager1.setManager(manager1);
manager1.AddEmployee(employee1);
company.employees.Add(manager1);
return company;
}
public void MarshalCompany(string filename)
{
Company po = BuildCompany ();
System.Runtime.Serialization.DataContractSerializer serializer = new DataContractSerializer (po.GetType ());
using (FileStream stream = File.Create (filename))
{
serializer.WriteObject(stream, po);
}
}
そして、私はたまたまこの出力を得ています...
<Company xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/XPathTest" z:Id="i1">
<employees>
<Person i:type="Manager" z:Id="i2">
<SSNum>1337</SSNum>
<manager i:nil="true"/>
<name>Jane Doe</name>
<employees>
<Person i:type="Employee" z:Id="i3">
<SSNum>8008132</SSNum>
<manager i:type="Manager" z:Ref="i2"/>
<name>John Smith</name>
</Person>
<Person i:type="Employee" z:Id="i4">
<SSNum>1138</SSNum>
<manager i:type="Manager" z:Ref="i2"/>
<name>Anne Jones</name>
</Person>
</employees>
</Person>
<Person i:type="Employee" z:Ref="i3"/>
<Person i:type="Employee" z:Ref="i4"/>
<Person i:type="Manager" z:Id="i5">
<SSNum>314</SSNum>
<manager i:nil="true"/>
<name>Boss Hog</name>
<employees>
<Person i:type="Manager" z:Ref="i2"/>
</employees>
</Person>
</employees>
</Company>
[DataMember(EmitDefaultValue=false)] 属性が機能しないのはなぜですか?
出力には次のようなものが表示されます
<manager i:nil="true"/>
サイズの理由と、何かがnull(要素なし)であってもjaxbが出力するものとの互換性のために、これは望ましくありません。
私が MSDN で読んだすべてのものや、他のスタックオーバーフローのページでさえ、これはうまくいくはずだと言っていますが、そうではありません。nil 要素がまだ存在する理由を理解するのを手伝ってくれる人に感謝します。そこに投稿されたコードは、「ngit」プロジェクトの Sharpen 名前空間 (Collections.List の単なるラッパーである Sharpen.AList の場合) を持っている場合、私にとっては機能するコードです。最近は Java/C# をよくやっています。
私がこれに興味を持っている理由は、基本的にJaxb 2.2.7でシリアル化されたいくつかのJavaクラスである大量の大量のデータを持っているためです。これは、Javaの類似クラスを持つC#クライアントにTCP経由で送信します。目標は、そのデータを C# クラスにアンマーシャリングすることです。残念ながら、シリアル化されたオブジェクトごとにユニバーサル参照トラッカーを自然に作成するメソッドを jaxb で見つけることができず、追跡して参照したいクラスごとに @XmlAdapter を手動で記述する必要がありました。DataContract はこれを自然かつ非常に簡単に行うようです。ただし、JAXB は出力 xml に null 要素への参照を配置しないため、DataContract が同じ動作を模倣していることを確認したいと思います。
ありがとうございました。