私はXMLデータに基づいてクラスを構築するコードジェネレータを持っています。それはデータをまっすぐに更新します。例えば、私はちょうど構造を表示する機能の大部分を省略。XMLファイルを書くためのコードを生成する最良の方法
Public Class RecordsNode
Inherits XmlClassBase
Private _current As RecordsItem
Private _errors As List(Of String)
Private _orphans As Dictionary(Of String, List(Of XmlClassBase))
Public Class BandNode
Inherits XmlClassBase
Private _current As BandItem
Private _list As BandItem()
Public Class AlbumNode
Inherits XmlClassBase
Private _current As AlbumItem
Private _list As AlbumItem()
Public Class DateNode
Inherits XmlClassBase
Private _current As DateItem
Private _list As DateItem()
Public Sub New()
_current = New DateItem(0)
End Sub
Public Overrides ReadOnly Property Attributes As Dictionary(Of String, String)
Get
Return _current.Attributes
End Get
End Property
Public ReadOnly Property Current As DateItem
Get
Return _current
End Get
End Property
Public ReadOnly Property List As DateItem()
Get
Return _list
End Get
End Property
Public Overrides Property Text As String
Get
Return _current.Text
End Get
Set(value As String)
_current.Text = value
End Set
End Property
Public Overrides Sub Add()
If _list IsNot Nothing Then
ReDim Preserve _list(_list.GetUpperBound(0) + 1)
Else
ReDim _list(0)
End If
_current = New DateItem(_list.GetUpperBound(0))
_list(_list.GetUpperBound(0)) = _current
End Sub
Public Function HasChildren() As Boolean
Return False
End Function
End Class
Public Class DateItem
Private _attributes As Dictionary(Of String, String)
Private _deleted As Boolean
Private _index As Integer
Private _text As String
Public Sub New(Index As Integer)
_index = Index
End Sub
Public ReadOnly Property Attributes As Dictionary(Of String, String)
Get
If _attributes Is Nothing Then
_attributes = New Dictionary(Of String, String)
End If
Return _attributes
End Get
End Property
Public ReadOnly Property ListIndex As Integer
Get
Return _index
End Get
End Property
Public Property Text As String
Get
Return _text
End Get
Set(value As String)
_text = value
End Set
End Property
End Class
Public Sub New()
_current = New AlbumItem(0)
End Sub
Public Overrides ReadOnly Property Attributes As Dictionary(Of String, String)
Get
Return _current.Attributes
End Get
End Property
Public ReadOnly Property Current As AlbumItem
Get
Return _current
End Get
End Property
Public ReadOnly Property List As AlbumItem()
Get
Return _list
End Get
End Property
Public Overrides Property Text As String
Get
Return _current.Text
End Get
Set(value As String)
_current.Text = value
End Set
End Property
Public ReadOnly Property Date As DateNode
Get
Return _current.Date
End Get
End Property
Public Overrides Sub Add()
If _list IsNot Nothing Then
ReDim Preserve _list(_list.GetUpperBound(0) + 1)
Else
ReDim _list(0)
End If
_current = New AlbumItem(_list.GetUpperBound(0))
_list(_list.GetUpperBound(0)) = _current
End Sub
Public Function HasChildren() As Boolean
Return False
End Function
End Class
Public Class AlbumItem
Private _attributes As Dictionary(Of String, String)
Private _deleted As Boolean
Private _index As Integer
Private _text As String
Private _Date As AlbumNode.DateNode
Public Sub New(Index As Integer)
_index = Index
_Date = New AlbumNode.DateNode
End Sub
Public ReadOnly Property Attributes As Dictionary(Of String, String)
Get
If _attributes Is Nothing Then
_attributes = New Dictionary(Of String, String)
End If
Return _attributes
End Get
End Property
Public ReadOnly Property ListIndex As Integer
Get
Return _index
End Get
End Property
Public Property Text As String
Get
Return _text
End Get
Set(value As String)
_text = value
End Set
End Property
Public ReadOnly Property Date As AlbumNode.DateNode
Get
Return _Date
End Get
End Property
End Class
Public Sub New()
_current = New BandItem(0)
End Sub
Public Overrides ReadOnly Property Attributes As Dictionary(Of String, String)
Get
Return _current.Attributes
End Get
End Property
Public ReadOnly Property Current As BandItem
Get
Return _current
End Get
End Property
Public ReadOnly Property List As BandItem()
Get
Return _list
End Get
End Property
Public Overrides Property Text As String
Get
Return _current.Text
End Get
Set(value As String)
_current.Text = value
End Set
End Property
Public ReadOnly Property Album As AlbumNode
Get
Return _current.Album
End Get
End Property
Public Overrides Sub Add()
If _list IsNot Nothing Then
ReDim Preserve _list(_list.GetUpperBound(0) + 1)
Else
ReDim _list(0)
End If
_current = New BandItem(_list.GetUpperBound(0))
_list(_list.GetUpperBound(0)) = _current
End Sub
Public Function HasChildren() As Boolean
Dim Children As Boolean
Return Children
End Function
End Class
Public Class BandItem
Private _attributes As Dictionary(Of String, String)
Private _deleted As Boolean
Private _index As Integer
Private _text As String
Private _Album As BandNode.AlbumNode
Public Sub New(Index As Integer)
_index = Index
_Album = New BandNode.AlbumNode
End Sub
Public ReadOnly Property Attributes As Dictionary(Of String, String)
Get
If _attributes Is Nothing Then
_attributes = New Dictionary(Of String, String)
End If
Return _attributes
End Get
End Property
Public ReadOnly Property ListIndex As Integer
Get
Return _index
End Get
End Property
Public Property Text As String
Get
Return _text
End Get
Set(value As String)
_text = value
End Set
End Property
Public ReadOnly Property Album As BandNode.AlbumNode
Get
Return _Album
End Get
End Property
End Class
Private _FilePath As String
Public Sub New()
_current = New RecordsItem(0)
_errors = New List(Of String)
_orphans = New Dictionary(Of String, List(Of XmlClassBase))
End Sub
Public Overrides ReadOnly Property Attributes As Dictionary(Of String, String)
Get
Return _current.Attributes
End Get
End Property
Public ReadOnly Property Current As RecordsItem
Get
Return _current
End Get
End Property
Public ReadOnly Property Errors As List(Of String)
Get
Return _errors
End Get
End Property
Public Property FilePath As String
Get
Return _FilePath
End Get
Set
_FilePath = value
End Set
End Property
Public ReadOnly Property OrphanNodes As Dictionary(Of String, List(Of XmlClassBase))
Get
Return _orphans
End Get
End Property
Public Overrides Property Text As String
Get
Return _current.Text
End Get
Set(value As String)
_current.Text = value
End Set
End Property
Public ReadOnly Property Band As BandNode
Get
Return _current.Band
End Get
End Property
Public Function Load() As Boolean
Dim Doc As xmldocument
Dim Node As XmlNode = Nothing
Dim r As Integer
Doc = New XmlDocument()
Doc.Load(_FilePath)
For Each Node In Doc.ChildNodes
If Node.Name <> "xml" Then 'Ignore any declarations.
Exit For 'Only 1 root node allowed, any others are ignored.
End If
Next
If Node.Attributes IsNot Nothing AndAlso Node.Attributes.Count > 0 Then
For r = 0 To Node.Attributes.Count - 1
Attributes.Add(Node.Attributes(r).Name, Node.Attributes(r).InnerText)
Next
End If
LoadChildren(Node, String.Empty, Me)
Return True
End Function
Public Function LoadChildren(xmlCurrent As XmlNode, ParentText As String, Parent As XmlClassBase) As XmlNode
Dim xmlNodeText As XmlNode
Dim Destination As XmlClassBase
Dim r As Integer
Dim strText As String
For Each xmlChildNode As XmlNode In xmlCurrent.ChildNodes
If xmlChildNode.NodeType = XmlNodeType.Element Then
Try
Destination = DirectCast(CallByName(Parent, xmlChildNode.Name, CallType.Get), XmlClassBase)
Catch mme As MissingMemberException
_errors.Add(mme.Message)
Destination = New XmlClassBase
AddOrphan(xmlChildNode.Name, Destination)
Catch ex As Exception
_errors.Add(ex.Message)
Throw
End Try
If Destination IsNot Nothing Then
If Destination.GetType.ToString <> "Records.XmlClassBase" Then
Destination.Add()
End If
strText = String.Empty
For Each xmlNodeText In xmlChildNode
If xmlNodeText.NodeType = XmlNodeType.Text Then
strText &= xmlNodeText.InnerText.Trim
End If
Next
If strText <> String.Empty Then
Destination.Text = strText
End If
If xmlChildNode.Attributes IsNot Nothing AndAlso xmlChildNode.Attributes.Count > 0 Then
For r = 0 To xmlChildNode.Attributes.Count - 1
Destination.Attributes.Add(xmlChildNode.Attributes(r).Name, xmlChildNode.Attributes(r).InnerText)
Next
End If
If xmlChildNode.HasChildNodes Then
LoadChildren(xmlChildNode, xmlChildNode.Name, Destination)
End If
End If
End If
Next
Return xmlCurrent
End Function
End Class
Public Class RecordsItem
Private _attributes As Dictionary(Of String, String)
Private _deleted As Boolean
Private _index As Integer
Private _text As String
Private _Band As RecordsNode.BandNode
Public Sub New(Index As Integer)
_index = Index
_Band = New RecordsNode.BandNode
End Sub
Public ReadOnly Property Attributes As Dictionary(Of String, String)
Get
If _attributes Is Nothing Then
_attributes = New Dictionary(Of String, String)
End If
Return _attributes
End Get
End Property
Public ReadOnly Property ListIndex As Integer
Get
Return _index
End Get
End Property
Public Property Text As String
Get
Return _text
End Get
Set(value As String)
_text = value
End Set
End Property
Public ReadOnly Property Band As RecordsNode.BandNode
Get
Return _Band
End Get
End Property
End Class
Loadメソッドは、できるだけ多くの作品(それは、これらに類似するクラスを作成します。私はこのXML
<?xml version="1.0" encoding="utf-8"?>
<Records>
<Band>Black Sabbath
<Album>
Paranoid
<Date>1977</Date>
</Album>
</Band>
<Band>Iron Maiden
<Album>
Killers
<Date>1981</Date>
</Album>
<Album>
PeiceOfMind
<Date>1983</Date>
</Album>
</Band>
</Records>
を持っていると言いますxmlElementsはコンピュータが扱うことができるので、私はそれが好きで簡潔ですが好きです。私の問題は、Saveメソッドでは、何が最善の方法であるかわからない。私はRecordsNodeの下にすべてのクラスを取得し、 。
私はこのような何かを使用することができますAssembly.GetExecutin gAssembly.GetTypes()しかし、hbowでは、RecordsNodeの子ではないすべてのクラスをフィルタリングしますか?
xmlはかなり大きい場合があります。私はちょっと気になる代わりに各クラスのコードを追加することができます。それは最も安全で醜いアプローチかもしれません。
その他のオプションはありますか?このクラスは顧客によって使用される可能性があるので、私はその宛先作業環境について何も保証することはできません。
ありがとうございました。
これは、C#とは何かを持っていないようだ、まだ私は 'を参照してくださいC# 'タグがあります。 – itsme86
ここで何をしようとしていますか(オブジェクトデータをテキストとして保存する)は、シリアル化と呼ばれるものです。 .NETにはXmlSerializerクラスが用意されています。 https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer(v=vs.110).aspx –
@Eric - 私はそれを見ました。その問題は、XMLを使ったSTARTです。そのクラスはオブジェクトで始まります。私は、シリアライズされた出力が元のXMLと一致するという信念はほとんどありません。 – John