たきるブログ

C#やOracleなどの情報を書いています。

【VB】独自要素を持つXMLを読み込む

<?xml version="1.0" encoding="utf-8" ?>
<configuration>  
  <settings>
    <database provider="aaa" datasource="bbb" userid="ccc" password="ddd" />

    <log enable="true" type="利用したいログクラス">
      <!-- 作成するログファイル名 -->
      <param name="File" value="C:\log-file.log" />

      <!-- ファイルの保持数 0は保持を行わない -->
      <param name="MaxSizeRollBackups" value="10" />

      <!-- 最大ファイルサイズ 0は制限しない -->
      <param name="MaximumFileSize" value="102400" />
    </log>
  </settings>
</configuration>

こんなXMLを読み込んでみよう!
デフォルトで操作できるconfigファイル名じゃ満足できない人は、独自要素を設けて幸せになれるかもしれない。

 
20101213_002.zip
まずXMLがこんな感じに変わる。
こういうクラスを使ってsettings要素を解析するんですよーってのを定義しる。
type属性は、"名前空間.クラス名, アセンブリ名"で指定する。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="settings" type="WindowsApplication1.SettingsSection, WindowsApplication1" />
  </configSections>
  
  <settings>
    <database provider="aaa" datasource="bbb" userid="ccc" password="ddd" />

    <log enable="true" type="利用したいログクラス">
      <!-- 作成するログファイル名 -->
      <param name="File" value="C:\log-file.log" />

      <!-- ファイルの保持数 0は保持を行わない -->
      <param name="MaxSizeRollBackups" value="10" />

      <!-- 最大ファイルサイズ 0は制限しない -->
      <param name="MaximumFileSize" value="102400" />
    </log>
  </settings>
</configuration>

んで、メインのソース。
予め、参照設定から「System.configuration」を追加しておくこと!

SettingsSection.vb

Imports System.Configuration

Public Class SettingsSection
    Inherits ConfigurationSection

    ''' <summary>
    ''' database要素を取得
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <ConfigurationProperty("database")> _
    Public Overridable ReadOnly Property database() As DatabaseElement
        Get
            Return CType(Me("database"), DatabaseElement)
        End Get
    End Property

    ''' <summary>
    ''' log要素を取得
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <ConfigurationProperty("log")> _
    Public Overridable ReadOnly Property log() As LogElement
        Get
            Return CType(Me("log"), LogElement)
        End Get
    End Property
End Class

DatabaseElement.vb

Imports System.Configuration

Public Class DatabaseElement
    Inherits ConfigurationElement

    ''' <summary>
    ''' provider属性を取得
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <ConfigurationProperty("provider", defaultValue:="", IsRequired:=False)> _
    Public Overridable ReadOnly Property Provider() As String
        Get
            Return CType(Me("provider"), String)
        End Get
    End Property

    ''' <summary>
    ''' datasource属性を取得
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <ConfigurationProperty("datasource", defaultValue:="", IsRequired:=True)> _
    Public Overridable ReadOnly Property Datasource() As String
        Get
            Return CType(Me("datasource"), String)
        End Get
    End Property

    ''' <summary>
    ''' userid属性を取得
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <ConfigurationProperty("userid", defaultValue:="", IsRequired:=True)> _
    Public Overridable ReadOnly Property UserId() As String
        Get
            Return CType(Me("userid"), String)
        End Get
    End Property

    ''' <summary>
    ''' password属性を取得
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <ConfigurationProperty("password", defaultValue:="", IsRequired:=True)> _
    Public Overridable ReadOnly Property Password() As String
        Get
            Return CType(Me("password"), String)
        End Get
    End Property
End Class

LogElement.vb

Imports System.Configuration

Public Class LogElement
    Inherits ConfigurationElement

    ''' <summary>
    ''' enable属性を取得
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <ConfigurationProperty("enable", IsRequired:=True)> _
    Public Overridable ReadOnly Property Enable() As String
        Get
            Return CType(Me("enable"), String)
        End Get
    End Property

    ''' <summary>
    ''' type属性を取得
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <ConfigurationProperty("type", IsRequired:=True)> _
    Public Overridable ReadOnly Property Type() As String
        Get
            Return CType(Me("type"), String)
        End Get
    End Property

    ''' <summary>
    ''' param要素(複数存在)を取得
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <ConfigurationProperty("", IsDefaultCollection:=True)> _
    Public Overridable ReadOnly Property ParamCollection() As ParamElementCollection
        Get
            Return CType(Me(""), ParamElementCollection)
        End Get
    End Property
End Class

ParamCollectionは、Param要素が複数あるので、こういう作り方になる。
IsDefaultCollection:=Trueで、複数あるんですよーってなるっぽい。

ParamElementCollection.vb

Imports System.Configuration

Public Class ParamElementCollection
    Inherits ConfigurationElementCollection

    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub New()
        AddElementName = "param"

    End Sub

    ''' <summary>
    ''' 指定したインデックスの要素を取得
    ''' </summary>
    ''' <param name="index"></param>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property getElement(ByVal index As Integer) As ParamElement
        Get
            Return CType(BaseGet(index), ParamElement)
        End Get
    End Property

    ''' <summary>
    ''' 指定したnameの要素を取得
    ''' </summary>
    ''' <param name="name"></param>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property getElement(ByVal name As String) As ParamElement
        Get
            Return CType(BaseGet(name), ParamElement)
        End Get
    End Property

    Public Function Contains(ByVal name As String) As Boolean
        Return BaseGet(name) IsNot Nothing
    End Function

    Protected Overloads Overrides Function CreateNewElement() As System.Configuration.ConfigurationElement
        Return New ParamElement()
    End Function

    ''' <summary>
    ''' 要素決定となるkey値
    ''' </summary>
    ''' <param name="element"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Protected Overrides Function GetElementKey(ByVal element As System.Configuration.ConfigurationElement) As Object
        Return (CType(element, ParamElement)).Name
    End Function
End Class

ParamElement.vb

Imports system.Configuration

Public Class ParamElement
    Inherits ConfigurationElement

    ''' <summary>
    ''' name属性を取得
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <ConfigurationProperty("name", IsKey:=True, IsRequired:=True)> _
    Public Overridable ReadOnly Property Name() As String
        Get
            Return CType(Me("name"), String)
        End Get
    End Property

    ''' <summary>
    ''' value属性を取得
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <ConfigurationProperty("value", IsRequired:=True)> _
    Public Overridable ReadOnly Property Value() As String
        Get
            Return CType(Me("value"), String)
        End Get
    End Property
End Class

実行させるコード

Imports System.Configuration

Public Class Window1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'xmlファイルを取得
        Dim filemap As ExeConfigurationFileMap = New ExeConfigurationFileMap()
        filemap.ExeConfigFilename = System.IO.Directory.GetCurrentDirectory() & "\app.config"
        Dim config As Configuration = ConfigurationManager.OpenMappedExeConfiguration(filemap, ConfigurationUserLevel.None)

        'settings要素について解析開始
        Dim settings As SettingsSection = CType(config.GetSection("settings"), SettingsSection)

        'databasse要素を操作
        Dim database As DatabaseElement = settings.database()
        MessageBox.Show("database.provider=" & database.Provider & vbCrLf & _
                "database.datasource=" & database.Datasource & vbCrLf & _
                "database.userid=" & database.UserId & vbCrLf & _
                "database.password=" & database.Password & vbCrLf)

        'log要素内のname="MaximumFileSize"のvalueを取得
        Dim para As ParamElement = settings.log.ParamCollection.getElement("MaximumFileSize")
        MessageBox.Show(para.Value)
    End Sub
End Class