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 Overloads) Sub 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:<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 String) As 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 String) As 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 String) In [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 |