1 #Region "Microsoft.VisualBasic::27e001b80e444b8c1062b34d12be842e, Microsoft.VisualBasic.Core\Text\Xml\Linq\DeserializeHandler.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class DeserializeHandler
35     
36     '         Properties: ReplaceXmlns
37     
38     '         Constructor: (+1 OverloadsSub New
39     '         Function: LoadXml, RemoveXmlns, ToString
40     
41     
42     ' /********************************************************************************/
43
44 #End Region
45
46 Imports System.Runtime.CompilerServices
47 Imports System.Text
48 Imports System.Xml.Serialization
49
50 Namespace Text.Xml.Linq
51
52     ''' <summary>
53     ''' The xml deserialize helper
54     ''' </summary>
55     Public Class DeserializeHandler(Of T As Class)
56
57         ReadOnly process As Func(Of StringString)
58         ''' <summary>
59         ''' Get type name that defined on the class type decoration with custom attributes:
60         ''' <see cref="XmlTypeAttribute"/> or <see cref="XmlRootAttribute"/>
61         ''' </summary>
62         ReadOnly Tname$ = GetType(T).GetNodeNameDefine
63
64         Public Property ReplaceXmlns As String
65
66         Sub New(xmlNode As String)
67             ' 2017-12-22
68             ' 假若对象是存储在一个数组之中的,那么,可能会出现的一种情况就是
69             ' 在类型的定义之中,使用了xmlelement重新定义了节点的名字
70             ' 例如 <XmlElement("A")>
71             ' 那么在生成的XML文件之中的节点名称就是A
72             ' 但是元素A的类型定义却是 Public Class B ... End Class
73             ' 因为A不等于B,所以将无法正确的加载XML节点数据
74             ' 在这里进行名称的替换来消除这种错误
75             If Tname = xmlNode Then
76                 ' 不需要进行替换
77                 process = Function(s) s
78             Else
79                 Dim leftTag% = 1 + xmlNode.Length
80                 Dim rightTag% = 3 + xmlNode.Length
81
82                 ' 在这里不尝试做直接替换,可能会误杀其他的节点
83                 process = Function(block)
84                               block = block.Trim(ASCII.CR, ASCII.LF, " "c, ASCII.TAB)
85                               block = block.Substring(leftTag, block.Length - leftTag)
86                               block = block.Substring(0, block.Length - rightTag)
87                               block = "<" & Tname & block & "</" & Tname & ">"
88
89                               Return block
90                           End Function
91             End If
92         End Sub
93
94         ReadOnly sb As New StringBuilder
95
96         <MethodImpl(MethodImplOptions.AggressiveInlining)>
97         Public Function RemoveXmlns(xml As StringAs String
98             Return xml.Replace($"xmlns=""{ReplaceXmlns}""""")
99         End Function
100
101         Public Function LoadXml(xml As StringAs T
102             Call sb.Clear()
103             Call sb.AppendLine("<?xml version=""1.0"" encoding=""utf-16""?>")
104             Call sb.AppendLine(process(xml))
105
106             If Not ReplaceXmlns.StringEmpty Then
107                 Call sb.Replace($"xmlns=""{ReplaceXmlns}""""")
108             End If
109
110             xml = sb.ToString
111
112             ' 对调整好的Xml文档执行反序列化操作
113             Return xml.LoadFromXml(Of T)
114         End Function
115
116         Public Overrides Function ToString() As String
117             Return $"LoadXml(Of {Tname})"
118         End Function
119     End Class
120 End Namespace