1 #Region "Microsoft.VisualBasic::adf7853a0f400413d214147ba630e932, Microsoft.VisualBasic.Core\Text\Xml\Xmlns.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 Xmlns
35     
36     '         Properties: [namespace], xmlns, xsd, xsi
37     
38     '         Constructor: (+1 OverloadsSub New
39     
40     '         Function: RootParser, ToString
41     
42     '         Sub: [Set], __replace, Clear, WriteNamespace
43     
44     
45     ' /********************************************************************************/
46
47 #End Region
48
49 Imports System.Text
50 Imports System.Text.RegularExpressions
51 Imports Microsoft.VisualBasic.ComponentModel.Collection
52 Imports Microsoft.VisualBasic.ComponentModel.DataSourceModel
53 Imports Microsoft.VisualBasic.Linq
54 Imports Microsoft.VisualBasic.Serialization.JSON
55
56 Namespace Text.Xml
57
58     ''' <summary>
59     ''' Xml namespace
60     ''' </summary>
61     Public Class Xmlns
62
63         ''' <summary>
64         ''' ``xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"``
65         ''' </summary>
66         Public Const DefaultXmlns As String = "xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"""
67
68         ''' <summary>
69         ''' ``xmlns=...``
70         ''' </summary>
71         ''' <returns></returns>
72         Public Property xmlns As String
73         ''' <summary>
74         ''' 枚举所有``xmlns:&lt;type>``开始的属性
75         ''' </summary>
76         ''' <returns></returns>
77         Public Property [namespace] As Dictionary(Of NamedValue(Of String))
78
79         Public Property xsd As String
80             Get
81                 Return Me(xmlns_xsd)
82             End Get
83             Set(value As String)
84                 [namespace](xmlns_xsd) = New NamedValue(Of String)(xmlns_xsd, value)
85             End Set
86         End Property
87
88         Public Property xsi As String
89             Get
90                 Return Me(xmlns_xsi)
91             End Get
92             Set(value As String)
93                 [namespace](xmlns_xsi) = New NamedValue(Of String)(xmlns_xsi, value)
94             End Set
95         End Property
96
97         Default Public ReadOnly Property ns(name As StringAs String
98             Get
99                 If [namespace].ContainsKey(name) Then
100                     Return [namespace](name).Value
101                 Else
102                     Return ""
103                 End If
104             End Get
105         End Property
106
107         Const xmlnsRegex As String = "\sxmlns:\S+="".+?"""
108         Const xmlns_xsd As String = "xmlns:xsd"
109         Const xmlns_xsi As String = "xmlns:xsi"
110
111         Sub New(root As String)
112             Dim s As String
113
114             [namespace] = New Dictionary(Of NamedValue(Of String))
115             s = Regex.Match(root, "xmlns="".+?""", RegexICSng).Value
116             xmlns = s.GetStackValue("""""""")
117
118             Dim nsList As String() =
119                 Regex.Matches(root, xmlnsRegex, RegexICSng) _
120                 .ToArray(AddressOf Trim)
121
122             For Each ns As String In nsList
123                 [namespace] += ns.GetTagValue("=") _
124                     .FixValue(Function(x) x.GetStackValue(""""""""))
125             Next
126         End Sub
127
128         ''' <summary>
129         ''' Set the value of a new xml namespace.(<paramref name="ns"/>命名空间参数不需要添加 xmlns: 前缀)
130         ''' </summary>
131         ''' <param name="ns"></param>
132         ''' <param name="value"></param>
133         Public Sub [Set](ns As String, value As String)
134             ns = $"xmlns:{ns}"
135             [namespace](ns) = New NamedValue(Of String)(ns, value)
136         End Sub
137
138         Public Sub Clear(ns$)
139             Call [Set](ns, "")
140         End Sub
141
142         ''' <summary>
143         ''' The parser for the xml root node.
144         ''' </summary>
145         ''' <param name="root"></param>
146         ''' <returns></returns>
147         Public Shared Function RootParser(root As StringAs NamedValue(Of Xmlns)
148             Dim ns As New Xmlns(root)
149             Dim name As String = root.Split.First
150             name = Mid(name, 2)
151             Return New NamedValue(Of Xmlns)(name, ns)
152         End Function
153
154         Public Overrides Function ToString() As String
155             Return Me.GetJson
156         End Function
157
158         ''' <summary>
159         ''' 
160         ''' </summary>
161         ''' <param name="xml"></param>
162         ''' <remarks>当前的这个对象是新值,需要替换掉文档里面的旧值</remarks>
163         Public Sub WriteNamespace(xml As StringBuilder, Optional usingDefault_xmlns As Boolean = False)
164             Dim rs As String = XmlDoc.__rootString(xml.ToString)
165             Dim root As Xmlns = New Xmlns(rs) ' old xmlns value
166             Dim ns As New StringBuilder(rs)  ' 可能还有其他的属性,所以在这里还不可以直接拼接字符串然后直接进行替换
167
168             For Each nsValue As NamedValue(Of StringIn [namespace].Values.SafeQuery
169                 Dim rootNs As String = root(nsValue.Name)
170
171                 If Not String.IsNullOrEmpty(rootNs) Then
172                     Dim s As String =
173                         If(String.IsNullOrEmpty(nsValue.Value),
174                         "",
175                         $"{nsValue.Name}=""{nsValue.Value}""")
176                     Call ns.Replace($"{nsValue.Name}=""{rootNs}""", s)
177                 Else
178                     If Not String.IsNullOrEmpty(nsValue.Value) Then
179                         Call __replace(ns, $"{nsValue.Name}=""{nsValue.Value}""")
180                     End If
181                 End If
182             Next
183
184             If Not String.IsNullOrEmpty(root.xmlns) Then
185                 Call ns.Replace($"xmlns=""{root.xmlns}""", "")
186             End If
187
188             If Not String.IsNullOrEmpty(xmlns) Then  ' 当前的xmlns值不为空值 ,则设置xmlns
189                 Call __replace(ns, $"xmlns=""{xmlns}""")
190             End If
191
192             If usingDefault_xmlns Then
193                 Call __replace(ns, DefaultXmlns)
194             End If
195
196             Call xml.Replace(rs, ns.ToString)
197         End Sub
198
199         Private Shared Sub __replace(ByRef sb As StringBuilder, value$)
200             Dim s$ = sb.ToString.TrimEnd(">"c).Trim
201             s &= " " & value & ">"
202             sb = New StringBuilder(s)
203         End Sub
204     End Class
205 End Namespace