都 2021 年了,竟然有人搞大数据时忽略 JSON 而去研究用 C# 把 XML 转换为 XML 的技术
在大数据项目开发过程中,ETL(Extract-Transform-Load)是必不可少。即便目前 JSON 非常流行,开发人员也有必定会有对远古系统的挑战,而 XML 格式的数据源作为经典存在浑身上下散发着浓浓 old money 的味道。
因为有 Newtonsoft.Json 这样优秀的 JSON 框架存在,开发人员可以很容易的对 JSON 格式的字符串反序列化。但是 XML 格式的数据就没有这么方便了:虽然 .NET 中内置了对 XML 序列化和反序列化的支持,但遇到需要对接外部数据时就不是很方便了。
使用 XmlReader 读取数据
从 XML 中提取目标数据最高效,也最麻烦的方式是直接使用 XmlReader :
<employee xmlns="urn:empl-hire">
<ID>12365</ID>
<hire-date>2003-01-08</hire-date>
<title>Accountant</title>
</employee>
使用以下代码对上述 hireDate.xml 文件读取:
using (XmlReader reader = XmlReader.Create("hireDate.xml")) {
// Move to the hire-date element.
reader.MoveToContent();
reader.ReadToDescendant("hire-date");
// Return the hire-date as a DateTime object.
DateTime hireDate = reader.ReadElementContentAsDateTime();
Console.WriteLine("Six Month Review Date: {0}", hireDate.AddMonths(6));
}
输出:
Six Month Review Date: 7/8/2003 12:00:00 AM
使用 XDocument 读取数据
在 .NET Framework 3.5 发布后的时间里,开发人员可以使用 XDocument 来生成和解析 XML 文档,这要比 XmlReader 方便的多:
string str =
@"<?xml version=""1.0""?>
<!-- comment at the root level -->
<Root>
<Child>Content</Child>
</Root>";
XDocument doc = XDocument.Parse(str);
Console.WriteLine(doc.XPathSelectElement("//Child"));
输出:
<Child>Content</Child>
但硬编码的 XPath 并不方便调试,而且需要时刻关注空引用的问题。在 XML 格式复杂、项目工程比较大时使用起来也不方便。
一种把 XML 转换为 XML 的技术: XSLT
在计算机科学中,可扩展样式表转换语言(英语:Extensible Stylesheet Language Transformations,缩写XSLT)是一种样式转换标记语言,可以将XML数据档转换为另外的XML或其它格式,如HTML网页,纯文字。XSLT最末的T字母表示英语中的“转换”(transformation)。
简单来说,开发人员可以借助 XSLT 技术编写一个 XML 文件,并使用该文件将一种 XML 格式转换为另一种 XML 。即:在对接复杂格式 XML 数据源时,开发人员可以编写一个后缀为 .xsl 的文件,并使用该文件将数据源格式转换为自己需要的格式(比如可以适配 XML 反序列化的格式)。
从一个简单的 XML 文件开始:
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
.
.
.
</catalog>
如果直接在浏览器打开这个文件:

假设我们只关心所有的 title 信息,可以使用下面的 cdcatalog.xsl 文件,该文件可以将 cdcatalog.xml 转为 XmlSerializer 所需要的格式:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsl:for-each select="catalog/cd">
<string>
<xsl:value-of select="title"/>
</string>
</xsl:for-each>
</ArrayOfString>
</xsl:template>
</xsl:stylesheet>
为了可以在浏览器中直接观察到转换效果,可以选择把 XSL 样式表链接到 XML 文档:向 XML 文档(”cdcatalog.xml”)添加 XSL 样式表引用即可。
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="cdcatalog.xsl"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
.
.
.
</catalog>
刷新浏览器,打开开发者工具:

也可以在: https://www.coderbusy.com/demos/2021/1531/cdcatalog.xml 查看在线示例。
从上面的操作可以看出,调试 XLS 文件的成本是很低的,开发者可以很容易对 XLS 文件进行更改,并在短时间之内得到运行结果。
在 C# 中使用 XSLT 技术
在 C# 中,可以使用 XslCompiledTransform进行 XSL 转换。以下代码展示这个转换过程:
XslCompiledTransform xsl = new XslCompiledTransform();
xsl.Load("cdcatalog.xsl");
var sb = new StringBuilder();
using (var sw = new StringWriter(sb))
{
using (var xw = new XmlTextWriter(sw) { Formatting = Formatting.Indented })
{
xsl.Transform("cdcatalog.xml", xw);
}
} var xml = sb.ToString();
Console.WriteLine(xml);
以上代码会产生如下输出:
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>Empire Burlesque</string>
<string>Hide your heart</string>
<string>Greatest Hits</string>
<string>Still got the blues</string>
<string>Eros</string>
.
.
.
</ArrayOfString>
反序列化 XML 字符串
转换 XML 不是目的,能直接拿到数据对象才是。以上的代码完成了格式转换,接着需要对转换好的 XML 字符串反序列化:
var xmlSerializer = new XmlSerializer(typeof(List<string>));
using (var ms = new emoryStream(Encoding.UTF8.GetBytes(xml)))
{
var list = (List<string>) xmlSerializer.Deserialize(ms);
foreach (var item in list)
{
Console.WriteLine(item);
}
}
以上代码借助 XmlSerializer 实现了反序列化功能,这会产生以下输出:
Empire Burlesque
Hide your heart
Greatest Hits
Still got the blues
Eros
...
总结与源码
本文所述的转换和反序列化技术已经在真实的生产环境中得到验证,千万级的数据处理也毫不费力。
本文包含的演示的代码和数据可以在 Gitee 上找到: https://gitee.com/coderbusy/demo/tree/master/hello-xslt/HelloXslt 。
都 2021 年了,竟然有人搞大数据时忽略 JSON 而去研究用 C# 把 XML 转换为 XML 的技术的更多相关文章
- 搞大数据,你不懂这三大数据处理趋势就OUT了
搞大数据,你不懂这三大数据处理趋势就OUT了 企业数据每年以PB级甚至上百PB爆炸式增长,越来越大的数据量正为扩大分析策略在企业应用软件领域的拓展提供了数据基础,但数据的价值是有时效性的,越早分析越能 ...
- 搞大数据,Java 工程师需要掌握哪些知识?
先看再点赞,给自己一点思考的时间,微信搜索[沉默王二]关注这个有颜值却假装靠才华苟且的程序员.本文 GitHub github.com/itwanger 已收录,里面还有一线大厂整理的面试题,以及我的 ...
- 话题讨论&征文--谈论大数据时我们在谈什么 获奖名单发布
从社会发展趋势的角度,非常明显大数据会是眼下肉眼可及的视野范围里能看到的最大趋势之中的一个.从传统IT 业到互联网.互联网到移动互联网,从以智能手机和Pad 为主要终端载体的移动互联网到可穿戴设备的移 ...
- asp.net mvc 4 json大数据异常 提示JSON字符长度超出限制的异常
今天客户突然过来找我说在后台添加了一篇超长的文章后,所有后台的文章都显示不出来了.后台的前端显示是用easyui的,返回的数据全是用json.根据客户的描述进行了同样的操作后,在firebug下发现a ...
- java开发的web下载大数据时的异常处理
同事用java开发了一个系统,其中有一个功能是下载大约10万笔数据到Excel中.当上线后,很多用户反映下载数据量大的时候就不能成功,但有时可以,所以结论就是系统不稳定,这个问题拖了很久没有解决. 在 ...
- WCF传送大数据时的错误“ 超出最大字符串内容长度配额”
格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出错: GetLzdtArticleResult.InnerException 消息是“反序 ...
- 发送大数据时,PDU的问题?
昨天发现通过 Ice发送请求传递一个大块数据时,当请求的体积大于1.2M后,直接抛出异常Connection Lost,对方peer或是断开了.通过防火墙配置排查,以及对同一网络同一机器的php服务p ...
- 谁说.NET不适合搞大数据,机器学习、人工智能
SciSharp Stack SciSharp STACK: https://scisharp.github.io/SciSharp/ 基于.NET的开源生态系统,用于数据科学.机器学习和AI. Sc ...
- 对于大数据量的Json解析
近几天做了一个项目,需要解析大量的json数据,有一万多条,以前我用的都是Gson包去自动解析,但是速度真是不敢恭维,于是我又去查了其它的方法,发现fastjson的解析,发现速度直的是很快,在此我不 ...
随机推荐
- 【linux】系统编程-8-Socket
目录 前言 11. 套接字 11.1 Socket简介 11.2 socket() 11.3 bind() 11.4 connect() 11.5 listen() 11.6 accept() 11. ...
- ElasticSearch实战系列十: ElasticSearch冷热分离架构
前言 本文主要介绍ElasticSearch冷热分离架构以及实现. 冷热分离架构介绍 冷热分离是目前ES非常火的一个架构,它充分的利用的集群机器的优劣来实现资源的调度分配.ES集群的索引写入及查询速度 ...
- markdown快捷输入
标题: 输入方式:#+空格+标题名,几级标题就敲几个# 注:最大支持六级标题 字体 加粗:在要加粗的字体前后加** 斜体:在要倾斜的字体前后加* 斜体加粗:在要倾斜并加粗的字体前后加*** 删除线:在 ...
- Topshelf一个用于使用.NET构建Windows服务框架
1 Topshelf是什么? Topshelf是用于托管使用.NET框架编写的Windows服务的框架.服务的创建得到简化,从而使开发人员可以创建一个简单的控制台应用程序,可以使用Topshelf将其 ...
- Dynamics CRM存放选项集记录的表
我们在做一些自定义查询的时候会去查询选项集字段的值,但是实体的选项集字段是一个整型字段,直接查询并不能找到对应的选项集的显示内容.所以我们需要找到存放选项集键值对的表来做关联查询找到我们想要的值. D ...
- Dynamics CRM各个版本的元数据浏览解决方案
https://docs.microsoft.com/en-us/dynamics365/customerengagement/on-premises/developer/browse-your-me ...
- KubeEdge EdgeMesh设计原理
EdgeMesh主要用来做边缘侧微服务的互访. ServiceMesh service mesh是一个服务网格的概念.在传统的架构里面都是通过像Dubbo来进行服务治理,服务治理的程序和我们应用程序强 ...
- 剑指offer--孩子们的游戏(圆圈中最后剩下的数字)
每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为牛客的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈.然后,他随机指定一个数m ...
- 记一次go中map并发引起的事故
错误使用map引发的血案 前言 场景复原 原因 参考 错误使用map引发的血案 前言 最近业务中,同事使用map来接收返回的结果,使用waitGroup来并发的处理执行返回的结果,结果上线之后,直接崩 ...
- ASP.NET Core扩展库之Http请求模拟
如今,完全独立的业务应用几乎不存在,不管是在企业内部微服务之间的调用,还是与外部第三方服务的调用,Http的API交互是常见的场景,这些实际情况给我们的开发带来了比较大的挑战,一是第三方服务可能会牵制 ...