|
|
連載
.NETで簡単XML
第11回 オブジェクトをXMLでシリアライズ(3)
株式会社ピーデー 川俣 晶
2003/11/22 |
|
|
要素のシーケンスとしての配列のシリアライズ
前回の最後に、以下のように書いた。
実際に実行した例を見ると、配列の中に入っているクラスもシリアライズされ、Personクラスの配列は、単純なPerson要素の繰り返しに置き換えられていることが分かるだろう。しかし、これだけでは、思い通りのXML文書を出力するには不十分である。例えば、この例では、Persons要素の子要素にpersons要素があり、その子要素にPerson要素があるため、少し不必要に要素の階層が深すぎる印象も受ける。
|
これらの問題に対処する方法は、次回に続くとしたが、それをここで解説する。つまり、Persons要素の子要素にpersons要素があり、その子要素にPerson要素があるため、少し不必要に要素の階層が深すぎるという問題に対処するために、階層を浅くする方法を解説してみよう、という意味である。
まず、シリアライズされるクラスを見てみよう。前回の「配列のシリアル化」のサンプル・プログラムとほとんど同じだが、ほぼ全体をもう一度掲載する。
Public Class Person
Private m_name As String = "未設定"
Private m_age As Integer = 0
Public Property Name() As String
Get
Return m_name
End Get
Set(ByVal Value As String)
m_name = Value
End Set
End Property
Public Property Age() As Integer
Get
Return m_age
End Get
Set(ByVal Value As Integer)
m_age = Value
End Set
End Property
End Class
Public Class Persons
<XmlElement()> Public persons(2) As Person
Public Sub SetPersons(ByVal person1 As Person, ByVal person2 As Person, ByVal person3 As Person)
persons(0) = person1
persons(1) = person2
persons(2) = person3
End Sub
Public Sub Dump()
For Each person As Person In persons
Trace.WriteLine(person.Name)
Trace.WriteLine(person.Age)
Next
End Sub
End Class |
|
サンプル・プログラム2-1:シリアライズされるクラス(VB.NET版/C#版) |
これを呼び出す側を記述してみよう。ただし、Form1_Loadメソッドと、deserializeSampleメソッドは今回最初の「派生クラスを含む配列のシリアライズ」のサンプル・プログラムと同じ内容になるので、省略している。
Private Sub serializeSample()
Dim person1 As New Person
person1.Name = "山田太郎"
person1.Age = 17
Dim person2 As New Person
person2.Name = "山田二郎"
person2.Age = 16
Dim person3 As New Person
person3.Name = "山田三郎"
person3.Age = 15
Dim persons As New Persons
persons.SetPersons(person1, person2, person3)
Dim serializer As XmlSerializer = New XmlSerializer(GetType(Persons))
Dim stream As FileStream = New FileStream("c:\sample.xml", FileMode.Create)
Try
serializer.Serialize(stream, persons)
Finally
stream.Close()
End Try
End Sub |
|
サンプル・プログラム2-2:シリアライズを行うメソッド(VB.NET版/C#版) |
これを実行すると以下のような結果が得られる。
また、生成されるXML文書は以下のようになる。
<?xml version="1.0"?>
<Persons xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<persons>
<Name>山田太郎</Name>
<Age>17</Age>
</persons>
<persons>
<Name>山田二郎</Name>
<Age>16</Age>
</persons>
<persons>
<Name>山田三郎</Name>
<Age>15</Age>
</persons>
</Persons> |
|
生成されるXML文書 |
さて、階層がどうなっているか、結果を調べてみよう。この結果を見ると、Persons要素の子要素にpersons要素があるが、その下に直接Name要素やAge要素があり、前回の例にはあったPerson要素は見あたらない。つまり、階層が1つ減って、すっきりしている。しかし、XML文書として不自然になったり、データの解釈があいまいな状態に陥ったりしているわけでもない。もともとXMLでは、同じ要素の繰り返しはよくあるデータ構造として用いられる。配列に相当する情報をXML文書に記録する場合、配列の中身のデータを繰り返し書き込むだけでもよく、配列であることを示す要素を強いて付けなくても済む場合が多い。
では、何が階層を浅くしてくれたのだろうか。それは、サンプル・プログラムに追加されたたった1つの属性である。配列の宣言に付いているXmlElement属性(System.Xml.Serialization.XmlElementAttributeクラス)がそれである。XmlElement属性といえば、前々回、前回にも要素の名前を指定する属性として登場しているが、ここではそれらとは違った機能を発揮していることになる。要素の名前を指定する場合は、XmlElement属性の引数に名前を指定したが、ここでは名前を指定してはいない。それどころか引数は1つもない。それにより、XmlElement属性が持つ本来の主要な機能、指定された対象を要素で表現するという機能だけでなく、XmlElement属性の「配列を返すフィールドまたはプロパティにXmlElementAttributeを適用すると、その配列内の項目はXML要素のシーケンスとしてエンコードされる」という機能も発揮されているわけである。XML要素のシーケンスとは、同じ種類の要素が繰り返し出現していることを意味する。
Insider.NET 記事ランキング
本日
月間