zoukankan      html  css  js  c++  java
  • 都 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 。

    欢迎来到:码农很忙
  • 相关阅读:
    1020.表-继承
    1019.模式(限定名)
    1018.行安全策略
    1017.权限
    1016.表结构修改
    1015.【转】oracle rowid and postgresql ctid
    1014.表-系统列
    20201227[java]同构字符串
    oCam_v4850录屏软件
    《软件定义网络中的异常流量检测研究进展》论文笔记
  • 原文地址:https://www.cnblogs.com/Soar1991/p/14806436.html
Copyright © 2011-2022 走看看