|
@@ -0,0 +1,554 @@
|
|
|
+
|
|
|
+using Newtonsoft.Json.Linq;
|
|
|
+using System.IO;
|
|
|
+using System.Text;
|
|
|
+using System.Xml;
|
|
|
+
|
|
|
+namespace Vit.Core.Util.Xml
|
|
|
+{
|
|
|
+ /// <summary>
|
|
|
+ ///
|
|
|
+ /// </summary>
|
|
|
+ public class XmlHelp
|
|
|
+ {
|
|
|
+ public const string jsonStringDemo = @"
|
|
|
+{
|
|
|
+ Declaration:{ ""version"":""1.0"",""encoding"":""utf-8"",""standalone"":null }
|
|
|
+ ,Children:
|
|
|
+ [
|
|
|
+ {
|
|
|
+ Tag:""soap12:Envelope""
|
|
|
+ , Attribute:{""xmlns:xsi"":""http://www.w3.org/2001/XMLSchema-instance"",""a"":""bbb""}
|
|
|
+ ,Children:
|
|
|
+ [
|
|
|
+ ""dddddddd"",
|
|
|
+ {Tag:""DoTransResult"", Children[""string""]
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+}
|
|
|
+";
|
|
|
+
|
|
|
+
|
|
|
+ public const string xmlStringDemo = @"
|
|
|
+//xml:
|
|
|
+<?xml version=""1.0"" encoding=""utf-8"" ?>
|
|
|
+<soap12:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" a=""bbb"" >
|
|
|
+ dddddddd
|
|
|
+ <DoTransResult> string</DoTransResult>
|
|
|
+</soap12:Envelope>
|
|
|
+";
|
|
|
+
|
|
|
+
|
|
|
+ #region XmlString To Json
|
|
|
+
|
|
|
+
|
|
|
+ /*
|
|
|
+ *
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+//*/
|
|
|
+
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ ///
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="xmlString"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static JObject XmlStringToJson(string xmlString)
|
|
|
+ {
|
|
|
+
|
|
|
+ //(x.1)创建文档对象
|
|
|
+ JObject joXml = new JObject();
|
|
|
+ XmlDocument doc = new XmlDocument();
|
|
|
+ //加载XML
|
|
|
+ doc.LoadXml(xmlString);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ #region (x.2) 头部信息
|
|
|
+ if (doc.ChildNodes[0] is XmlDeclaration dec)
|
|
|
+ {
|
|
|
+ var joDeclaration = new JObject();
|
|
|
+ joXml["Declaration"] = joDeclaration;
|
|
|
+
|
|
|
+ if (!string.IsNullOrEmpty(dec.Version))
|
|
|
+ joDeclaration["version"] = dec.Version;
|
|
|
+ if (!string.IsNullOrEmpty(dec.Encoding))
|
|
|
+ joDeclaration["encoding"] = dec.Encoding;
|
|
|
+ if (!string.IsNullOrEmpty(dec.Standalone))
|
|
|
+ joDeclaration["standalone"] = dec.Standalone;
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region (x.3) Children
|
|
|
+ JArray joChildren = new JArray();
|
|
|
+ joXml["Children"] = joChildren;
|
|
|
+ joChildren.Add(ParseXmlNode(doc.DocumentElement));
|
|
|
+ #endregion
|
|
|
+
|
|
|
+
|
|
|
+ return joXml;
|
|
|
+
|
|
|
+
|
|
|
+ #region function ParseXmlNode
|
|
|
+
|
|
|
+
|
|
|
+ JToken ParseXmlNode(XmlNode xmlNode)
|
|
|
+ {
|
|
|
+ if (null == xmlNode) return null;
|
|
|
+
|
|
|
+ if (xmlNode is XmlText xmlText) return xmlText.Data;
|
|
|
+
|
|
|
+ if (!(xmlNode is XmlElement xmlElem)) return null;
|
|
|
+
|
|
|
+ #region 处理XmlElement
|
|
|
+
|
|
|
+
|
|
|
+ /*
|
|
|
+
|
|
|
+ { Tag:"soap12:Envelope"
|
|
|
+ ,Attribute:{"xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance"}
|
|
|
+ ,Children:[
|
|
|
+ "dddddddd",
|
|
|
+ {Tag:"DoTransResult",Children["string"] }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ */
|
|
|
+ //(x.x.1) CreateElement
|
|
|
+ JObject joElem = new JObject();
|
|
|
+ joElem["Tag"] = xmlElem.Name;
|
|
|
+
|
|
|
+ //(x.x.2) Attribute
|
|
|
+ var Attribute = xmlElem.Attributes;
|
|
|
+ if (null != Attribute)
|
|
|
+ {
|
|
|
+ var joAttribute = new JObject();
|
|
|
+ joElem["Attribute"] = joAttribute;
|
|
|
+ foreach (XmlAttribute attr in Attribute)
|
|
|
+ {
|
|
|
+ joAttribute[attr.Name] = attr.Value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //(x.x.3) Children
|
|
|
+ var _Children = xmlElem.ChildNodes;
|
|
|
+ if (xmlElem.HasChildNodes)
|
|
|
+ {
|
|
|
+ var _joChildren = new JArray();
|
|
|
+ joElem["Children"] = _joChildren;
|
|
|
+
|
|
|
+ foreach (XmlNode child in xmlElem.ChildNodes)
|
|
|
+ {
|
|
|
+ var joChild = ParseXmlNode(child);
|
|
|
+ if (null != joChild)
|
|
|
+ _joChildren.Add(joChild);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return joElem;
|
|
|
+ #endregion
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ #region Json To XmlDocument
|
|
|
+ /// <summary>
|
|
|
+ ///
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="joXml"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static XmlDocument JsonToXmlDocument(JObject joXml)
|
|
|
+ {
|
|
|
+
|
|
|
+ JObject joDeclaration = joXml["Declaration"]?.Value<JObject>();
|
|
|
+
|
|
|
+
|
|
|
+ //(x.1)创建文档对象
|
|
|
+ XmlDocument doc = new XmlDocument();
|
|
|
+
|
|
|
+
|
|
|
+ #region (x.2) 头部信息
|
|
|
+ //声明XML头部信息
|
|
|
+ XmlDeclaration dec = doc.CreateXmlDeclaration(joDeclaration?["version"]?.Value<string>() ?? "1.0", joDeclaration?["encoding"]?.Value<string>() ?? "UTF-8", joDeclaration?["standalone"]?.Value<string>());
|
|
|
+
|
|
|
+ //添加进doc对象子节点
|
|
|
+ doc.AppendChild(dec);
|
|
|
+ #endregion
|
|
|
+
|
|
|
+
|
|
|
+ #region (x.3) 递归创建子节点
|
|
|
+
|
|
|
+ var Children = joXml["Children"]?.Value<JArray>();
|
|
|
+ if (null != Children)
|
|
|
+ {
|
|
|
+ foreach (JToken child in Children)
|
|
|
+ {
|
|
|
+ var xmlChild = ToXmlNode(doc, child);
|
|
|
+ if (null != xmlChild)
|
|
|
+ doc.AppendChild(xmlChild);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ //(x.4) return
|
|
|
+ return doc;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ #region function ToXmlNode
|
|
|
+
|
|
|
+
|
|
|
+ XmlNode ToXmlNode(XmlDocument xmlDoc, JToken elem)
|
|
|
+ {
|
|
|
+ //(x.1)为string
|
|
|
+ if (elem.Type == JTokenType.String)
|
|
|
+ {
|
|
|
+ return xmlDoc.CreateTextNode(elem.Value<string>());
|
|
|
+ }
|
|
|
+
|
|
|
+ //(x.2)不为JOject 返回null
|
|
|
+ if (elem.Type != JTokenType.Object)
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ #region (x.3)为JOject
|
|
|
+
|
|
|
+
|
|
|
+ /*
|
|
|
+
|
|
|
+ { Tag:"soap12:Envelope"
|
|
|
+ ,Attribute:{"xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance"}
|
|
|
+ ,Children:[
|
|
|
+ "dddddddd",
|
|
|
+ {Tag:"DoTransResult",Children["string"] }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ */
|
|
|
+ //(x.x.1) CreateElement
|
|
|
+ XmlElement xmlElem = xmlDoc.CreateElement(elem["Tag"]?.Value<string>());
|
|
|
+
|
|
|
+ //(x.x.2) Attribute
|
|
|
+ var Attribute = elem["Attribute"]?.Value<JObject>();
|
|
|
+ if (null != Attribute)
|
|
|
+ {
|
|
|
+ foreach (var kv in Attribute)
|
|
|
+ {
|
|
|
+ xmlElem.SetAttribute(kv.Key, kv.Value.Value<string>());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //(x.x.3) Children
|
|
|
+ var _Children = elem["Children"]?.Value<JArray>();
|
|
|
+ if (null != _Children)
|
|
|
+ {
|
|
|
+ foreach (JToken child in _Children)
|
|
|
+ {
|
|
|
+ var xmlChild = ToXmlNode(xmlDoc, child);
|
|
|
+ if (null != xmlChild)
|
|
|
+ xmlElem.AppendChild(xmlChild);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return xmlElem;
|
|
|
+ #endregion
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region XmlDocument To String
|
|
|
+ public string XmlDocumentToString(XmlDocument doc)
|
|
|
+ {
|
|
|
+ using (StringWriter sw = new StringWriter())
|
|
|
+ using (XmlTextWriter xmlTextWriter = new XmlTextWriter(sw))
|
|
|
+ {
|
|
|
+ doc.WriteTo(xmlTextWriter);
|
|
|
+ return sw.ToString();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+
|
|
|
+ #region Json To XmlString
|
|
|
+
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 直接字符串拼接构建XmlString
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="joXml"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static string JsonToXmlString(JObject joXml)
|
|
|
+ {
|
|
|
+ /*
|
|
|
+<?xml version="1.0" encoding="utf-8"?>
|
|
|
+<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
|
|
|
+ <soap12:Body>
|
|
|
+ <DoTrans xmlns="http://tempuri.org/">
|
|
|
+ <transCode>string</transCode>
|
|
|
+ <inJsonString>string</inJsonString>
|
|
|
+ </DoTrans>
|
|
|
+ </soap12:Body>
|
|
|
+</soap12:Envelope>
|
|
|
+ */
|
|
|
+
|
|
|
+ JObject joDeclaration = joXml["Declaration"]?.Value<JObject>();
|
|
|
+
|
|
|
+
|
|
|
+ //(x.1)创建文档对象
|
|
|
+ StringBuilder xmlBuilder = new StringBuilder(1000);
|
|
|
+
|
|
|
+ JToken token;
|
|
|
+
|
|
|
+ #region (x.2) 头部信息
|
|
|
+ //xmlBuilder.Append("<?xml version="1.0" encoding="utf - 8"?>");
|
|
|
+ xmlBuilder.Append("<?xml");
|
|
|
+
|
|
|
+ //version
|
|
|
+ if (null != (token = joDeclaration?["version"]))
|
|
|
+ {
|
|
|
+ xmlBuilder.Append(" version=\"");
|
|
|
+ AppendXmlStr(xmlBuilder, token.Value<string>());
|
|
|
+ xmlBuilder.Append("\"");
|
|
|
+ }
|
|
|
+
|
|
|
+ //encoding
|
|
|
+ if (null != (token = joDeclaration?["encoding"]))
|
|
|
+ {
|
|
|
+ xmlBuilder.Append(" encoding=\"");
|
|
|
+ AppendXmlStr(xmlBuilder, token.Value<string>());
|
|
|
+ xmlBuilder.Append("\"");
|
|
|
+ }
|
|
|
+
|
|
|
+ //standalone
|
|
|
+ if (null != (token = joDeclaration?["standalone"]))
|
|
|
+ {
|
|
|
+ xmlBuilder.Append(" standalone=\"");
|
|
|
+ AppendXmlStr(xmlBuilder, token.Value<string>());
|
|
|
+ xmlBuilder.Append("\"");
|
|
|
+ }
|
|
|
+ xmlBuilder.Append("?>");
|
|
|
+ #endregion
|
|
|
+
|
|
|
+
|
|
|
+ #region (x.3) 递归创建子节点
|
|
|
+
|
|
|
+ var Children = joXml["Children"]?.Value<JArray>();
|
|
|
+ if (null != Children)
|
|
|
+ {
|
|
|
+ foreach (JToken child in Children)
|
|
|
+ {
|
|
|
+ AppendXmlNode(xmlBuilder, child);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region (x.4) ToString
|
|
|
+ return xmlBuilder.ToString();
|
|
|
+ #endregion
|
|
|
+
|
|
|
+
|
|
|
+ #region function AppendXmlNode
|
|
|
+
|
|
|
+
|
|
|
+ void AppendXmlNode(StringBuilder builder, JToken elem)
|
|
|
+ {
|
|
|
+ //(x.1)为string
|
|
|
+ if (elem.Type == JTokenType.String)
|
|
|
+ {
|
|
|
+ AppendXmlStr(xmlBuilder, elem.Value<string>());
|
|
|
+ }
|
|
|
+
|
|
|
+ //(x.2)不为JOject 返回null
|
|
|
+ if (elem.Type != JTokenType.Object)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ #region (x.3)为JOject
|
|
|
+ /*
|
|
|
+ <DoTrans xmlns="http://tempuri.org/">
|
|
|
+ <transCode>string</transCode>
|
|
|
+ <inJsonString>string</inJsonString>
|
|
|
+ </DoTrans>
|
|
|
+
|
|
|
+ { Tag:"soap12:Envelope"
|
|
|
+ ,Attribute:{"xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance"}
|
|
|
+ ,Children:[
|
|
|
+ "dddddddd",
|
|
|
+ {Tag:"DoTransResult",Children["string"] }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ */
|
|
|
+ var tag = elem["Tag"]?.Value<string>();
|
|
|
+ //(x.x.1) 开始标签
|
|
|
+ builder.Append("<");
|
|
|
+ AppendXmlStr(xmlBuilder, tag);
|
|
|
+
|
|
|
+
|
|
|
+ //(x.x.2) Attribute
|
|
|
+ var Attribute = elem["Attribute"]?.Value<JObject>();
|
|
|
+ if (null != Attribute)
|
|
|
+ {
|
|
|
+ foreach (var kv in Attribute)
|
|
|
+ {
|
|
|
+ builder.Append(" ");
|
|
|
+ AppendXmlStr(xmlBuilder, kv.Key);
|
|
|
+ builder.Append("=\"");
|
|
|
+ AppendXmlStr(xmlBuilder, kv.Value.Value<string>());
|
|
|
+ builder.Append("\"");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ builder.Append(">");
|
|
|
+
|
|
|
+ //(x.x.3) Children
|
|
|
+ var _Children = elem["Children"]?.Value<JArray>();
|
|
|
+ if (null != _Children)
|
|
|
+ {
|
|
|
+ foreach (JToken child in _Children)
|
|
|
+ {
|
|
|
+ AppendXmlNode(builder, child);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //(x.x.4) 结束标签
|
|
|
+ builder.Append("</");
|
|
|
+ AppendXmlStr(xmlBuilder, tag);
|
|
|
+ builder.Append(">");
|
|
|
+ #endregion
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+
|
|
|
+ #region Util
|
|
|
+
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// <para>向xml 的 内容 转换。 </para>
|
|
|
+ /// <para>例如 转换为 <a title="">ok</a> 中a标签的内容体(innerHTML) </para>
|
|
|
+ /// <para>或 转换为 <a title="">ok</a> 中title的值。 </para>
|
|
|
+ /// <para> </para>
|
|
|
+ /// <para>转换 " & < > 为 &quot; &amp; &lt; &gt; 。</para>
|
|
|
+ /// <para>注: ' 对应 &apos; ,但有些浏览器不支持,故此函数不转换。 </para>
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="str">若为 空 或 空字符串,则原样返回</param>
|
|
|
+ /// <returns></returns>
|
|
|
+ static string StrToXmlStr(string str)
|
|
|
+ {
|
|
|
+ if (string.IsNullOrEmpty(str))
|
|
|
+ {
|
|
|
+ return str;
|
|
|
+ }
|
|
|
+ StringBuilder builder = new StringBuilder();
|
|
|
+ foreach (char c in str)
|
|
|
+ {
|
|
|
+ switch (c)
|
|
|
+ {
|
|
|
+ case '"':
|
|
|
+ builder.Append(""");
|
|
|
+ break;
|
|
|
+ case '&':
|
|
|
+ builder.Append("&");
|
|
|
+ break;
|
|
|
+ //case '\'':
|
|
|
+ // builder.Append("'");
|
|
|
+ // break;
|
|
|
+ case '<':
|
|
|
+ builder.Append("<");
|
|
|
+ break;
|
|
|
+ case '>':
|
|
|
+ builder.Append(">");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ builder.Append(c);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return builder.ToString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// <para>向xml 的 内容 转换 并追加到 builder。 </para>
|
|
|
+ /// <para>例如 转换为 <a title="">ok</a> 中a标签的内容体(innerHTML) </para>
|
|
|
+ /// <para>或 转换为 <a title="">ok</a> 中title的值。 </para>
|
|
|
+ /// <para> </para>
|
|
|
+ /// <para>转换 " & < > 为 &quot; &amp; &lt; &gt; 。 </para>
|
|
|
+ /// <para>注: ' 对应 &apos; ,但有些浏览器不支持,故此函数不转换。 </para>
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="builder">不可为空</param>
|
|
|
+ /// <param name="str">若为 空 或 空字符串,则原样返回</param>
|
|
|
+ /// <returns>原 builder</returns>
|
|
|
+ static StringBuilder AppendXmlStr(StringBuilder builder, string str)
|
|
|
+ {
|
|
|
+ if (string.IsNullOrEmpty(str))
|
|
|
+ {
|
|
|
+ return builder;
|
|
|
+ }
|
|
|
+ foreach (char c in str)
|
|
|
+ {
|
|
|
+ switch (c)
|
|
|
+ {
|
|
|
+ case '"':
|
|
|
+ builder.Append(""");
|
|
|
+ break;
|
|
|
+ case '&':
|
|
|
+ builder.Append("&");
|
|
|
+ break;
|
|
|
+ //case '\'':
|
|
|
+ // builder.Append("'");
|
|
|
+ // break;
|
|
|
+ case '<':
|
|
|
+ builder.Append("<");
|
|
|
+ break;
|
|
|
+ case '>':
|
|
|
+ builder.Append(">");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ builder.Append(c);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return builder;
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ }
|
|
|
+}
|