整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          都2021年竟然有人搞大數(shù)據(jù)忽略JSON去研究C#把XML轉(zhuǎn)換為XML的技術(shù)

          大數(shù)據(jù)項(xiàng)目開發(fā)過程中,ETL(Extract-Transform-Load)必不可少。即使目前 JSON 非常流行,開發(fā)人員也必定有機(jī)會面對遠(yuǎn)古系統(tǒng)的挑戰(zhàn),而 XML 格式的數(shù)據(jù)源作為經(jīng)典存在渾身上下散發(fā)著濃濃 old money 的味道。

          因?yàn)橛?Newtonsoft.Json 這樣優(yōu)秀的 JSON 框架存在,開發(fā)人員可以很容易的對 JSON 格式的字符串反序列化。但是 XML 格式的數(shù)據(jù)就沒有這么方便了:雖然 .NET 中內(nèi)置了對 XML 序列化和反序列化的支持,但遇到需要對接外部數(shù)據(jù)時(shí)就不是很方便了。

          使用 XmlReader 讀取數(shù)據(jù)

          從 XML 中提取目標(biāo)數(shù)據(jù)最高效,也最麻煩的方式是直接使用 XmlReader :

          <employee xmlns="urn:empl-hire">
          <ID>12365</ID>
          <hire-date>2003-01-08</hire-date>
          <title>Accountant</title>
          </employee>

          使用以下代碼對上述 hireDate.xml 文件讀?。?/span>

          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 讀取數(shù)據(jù)

          在 .NET Framework 3.5 發(fā)布后的時(shí)間里,開發(fā)人員可以使用 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 并不方便調(diào)試,而且需要時(shí)刻關(guān)注空引用的問題。在 XML 格式復(fù)雜、項(xiàng)目工程比較大時(shí)使用起來也不方便。

          一種把 XML 轉(zhuǎn)換為 XML 的技術(shù): XSLT

          在計(jì)算機(jī)科學(xué)中,可擴(kuò)展樣式表轉(zhuǎn)換語言(英語:Extensible Stylesheet Language Transformations,縮寫XSLT)是一種樣式轉(zhuǎn)換標(biāo)記語言,可以將XML數(shù)據(jù)檔轉(zhuǎn)換為另外的XML或其它格式,如HTML網(wǎng)頁,純文字。XSLT最末的T字母表示英語中的“轉(zhuǎn)換”(transformation)。

          簡單來說,開發(fā)人員可以借助 XSLT 技術(shù)編寫一個(gè) XML 文件,并使用該文件將一種 XML 格式轉(zhuǎn)換為另一種 XML 。即:在對接復(fù)雜格式 XML 數(shù)據(jù)源時(shí),開發(fā)人員可以編寫一個(gè)后綴為 .xsl 的文件,并使用該文件將數(shù)據(jù)源格式轉(zhuǎn)換為自己需要的格式(比如可以適配 XML 反序列化的格式)。

          從一個(gè)簡單的 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>

          如果直接在瀏覽器打開這個(gè)文件:

          假設(shè)我們只關(guān)心所有的 title 信息,可以使用下面的 cdcatalog.xsl 文件,該文件可以將 cdcatalog.xml 轉(zhuǎn)為 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>

          為了可以在瀏覽器中直接觀察到轉(zhuǎn)換效果,可以選擇把 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>

          刷新瀏覽器,打開開發(fā)者工具:

          也可以在: https://www.coderbusy.com/demos/2021/1531/cdcatalog.xml 查看在線示例。

          從上面的操作可以看出,調(diào)試 XLS 文件的成本是很低的,開發(fā)者可以很容易對 XLS 文件進(jìn)行更改,并在短時(shí)間之內(nèi)得到運(yùn)行結(jié)果。

          在 C# 中使用 XSLT 技術(shù)

          在 C# 中,可以使用 XslCompiledTransform 進(jìn)行 XSL 轉(zhuǎn)換。以下代碼展示這個(gè)轉(zhuǎn)換過程:

          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);

          以上代碼會產(chǎn)生如下輸出:

          <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 字符串

          轉(zhuǎn)換 XML 不是目的,能直接拿到數(shù)據(jù)對象才是。以上的代碼完成了格式轉(zhuǎn)換,接著需要對轉(zhuǎn)換好的 XML 字符串反序列化:

          var xmlSerializer = new XmlSerializer(typeof(List<string>));
          using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
          {
           var list = (List<string>) xmlSerializer.Deserialize(ms);
          foreach (var item in list)
          {
           Console.WriteLine(item);
          }
          }

          以上代碼借助 XmlSerializer 實(shí)現(xiàn)了反序列化功能,這會產(chǎn)生以下輸出:

          Empire Burlesque
          Hide your heart
          Greatest Hits
          Still got the blues
          Eros
          ...

          總結(jié)與源碼

          本文所述的轉(zhuǎn)換和反序列化技術(shù)已經(jīng)在真實(shí)的生產(chǎn)環(huán)境中得到驗(yàn)證,千萬級的數(shù)據(jù)處理也毫不費(fèi)力。

          本文包含的演示的代碼和數(shù)據(jù)可以在 Gitee 上找到:

          https://gitee.com/coderbusy/demo/tree/master/hello-xslt/HelloXslt

          者:前端小智 來源:大遷世界

          .md文件是markdown的一種標(biāo)記語言,和html比較起來,更簡單快捷,主要體現(xiàn)在:標(biāo)記符的數(shù)量和書寫上。

          • 標(biāo)記符的數(shù)量:html文檔需要用到數(shù)量繁多的標(biāo)記符,再輔以css來控制樣式和排版,而markdown文檔只需要四個(gè)基本的標(biāo)記符號就能完成同樣的事。
          • 標(biāo)記符的書寫:HTML文檔內(nèi)容需要同時(shí)標(biāo)記開始和結(jié)束這是一個(gè)網(wǎng)頁,而markdown文檔則只要在開始位置標(biāo)記即可# 這是一個(gè)md文檔。下面介紹如何實(shí)現(xiàn)將.md文件轉(zhuǎn)換成.html文件。

          方式一:使用i5ting_toc插件

          需要先安裝npm(安裝node.js后會自帶npm),然后才能安裝i5ting插件:

          npm install i5ting_toc -g

          執(zhí)行命令行生成html文件,在輸入前要進(jìn)入到對應(yīng)根目錄下:

          i5ting_toc -f **.md

          需要注意的是:寫md文檔的特殊符號時(shí)記得添加空格。小技巧:如何快速在當(dāng)前目錄打開cmd?選擇當(dāng)前目錄,按住shift,然后鼠標(biāo)右鍵在此處打開命令窗口(在此處打開powerShell窗口)。

          方式二:使用gitbook

          同樣先需要安裝node,然后運(yùn)行:

          npm i gitbook gitbook-cli -g

          生成md文件,這個(gè)命令會生成相應(yīng)的md的文件,然后在相應(yīng)的文件里寫你的內(nèi)容即可:

          gitbook init

          md轉(zhuǎn)html,生成一個(gè)_doc目錄,打開就可以看到你html文件了。

          gitbook build

          方式三:利用前端代碼

          實(shí)現(xiàn)原理是采用node.js搭建服務(wù)器,讀取md文件轉(zhuǎn)化為html片斷。瀏覽器發(fā)送ajax請求獲取片段后再渲染生成html網(wǎng)頁。

          node代碼:

          var express = require('express');

          var http = require('http');

          var fs = require('fs');

          var bodyParser = require('body-parser');

          var marked = require('marked'); // 將md轉(zhuǎn)化為html的js包

          var app = express();


          app.use(express.static('src')); //加載靜態(tài)文件

          var urlencodedParser = bodyParser.urlencoded({ extended: false });


          app.get('/getMdFile',urlencodedParser, function(req, res) {

          var data = fs.readFileSync('src/test.md', 'utf-8'); //讀取本地的md文件

          res.end(JSON.stringify({

          body : marked(data)

          }));

          } );


          //啟動端口監(jiān)聽

          var server = app.listen(8088, function () {

          var host = server.address().address;

          var port = server.address().port;

          console.log("應(yīng)用實(shí)例,訪問地址為 http://%s:%s", host, port)

          });

          前端html:

          <div id="content"> <h1 class="title">md-to-HTML web app</h1> <div id="article"> </div></div><script type="text/JavaScript" src="js/jquery-1.11.3.min.js"></script><script> var article = document.getElementById('article'); $.ajax({ url: "/getMdFile", success: function(result) { console.log('數(shù)據(jù)獲取成功'); article.innerHTML = JSON.parse(result).body; }, error: function (err) { console.log(err); article.innerHTML = '<p>獲取數(shù)據(jù)失敗</p>'; } });</script>

          面是我們?nèi)绾卧?JavaScript 中輕松地將 JSON 轉(zhuǎn)換為 CSV:

          function jsonToCsv(items) {
            const header = Object.keys(items[0]);  const headerString = header.join(',');  // handle null or undefined values here
            const replacer = (key, value) => value ?? '';  const rowItems = items.map((row) =>
              header
                .map((fieldName) => JSON.stringify(row[fieldName], replacer))
                .join(',')
            );  // join header and body, and break into separate lines
            const csv = [headerString, ...rowItems].join('\r\n');  return csv;
          }const obj = [
            { color: 'red', maxSpeed: 120, age: 2 },
            { color: 'blue', maxSpeed: 100, age: 3 },
            { color: 'green', maxSpeed: 130, age: 2 },
          ];const csv = jsonToCsv(obj);console.log(csv);

          這將是 CSV 輸出:

          color,maxSpeed,age
          "red",120,2
          "blue",100,3
          "green",130,2


          了解步驟

          我們創(chuàng)建了一個(gè)可重用的 jsonToCsv() 函數(shù)來讓我們將多個(gè) JSON 字符串轉(zhuǎn)換為 CSV。 它需要一個(gè)包含對象的數(shù)組。 每個(gè)對象將在 CSV 輸出中占據(jù)一行。

          我們在此函數(shù)中所做的第一件事是獲取將用于 CSV 標(biāo)頭的所有鍵。 我們希望數(shù)組中的所有對象都具有相同的鍵,因此我們使用 Object.keys() 方法將鍵從第一個(gè)對象項(xiàng)中提取到數(shù)組中。

          const obj = [
            { color: 'red', maxSpeed: 120, age: 2 },
            { color: 'blue', maxSpeed: 100, age: 3 },
            { color: 'green', maxSpeed: 130, age: 2 },
          ];// { color: 'red', maxSpeed: 120, age: 2 }
          console.log(obj[0]);// [ 'color', 'maxSpeed', 'age' ]
          console.log(Object.keys(obj[0]));

          獲取鍵后,我們調(diào)用數(shù)組的 join() 方法將所有元素連接成 CSV 標(biāo)頭字符串。

          const header = ['color', 'maxSpeed', 'age'];const headerString = arr.join(',');console.log(headerString); // color,maxSpeed,age

          接下來,我們創(chuàng)建一個(gè)函數(shù),該函數(shù)將作為回調(diào)傳遞給 JSON.stringify() 函數(shù)的 replacer 參數(shù)。 此函數(shù)將處理 JSON 數(shù)組中對象的未定義或空屬性值。

          const obj = { prop1: 'Earth', prop2: undefined };// replace undefined property values with empty string ('')
          const replacer = (key, value) => value ?? '';const str = JSON.stringify(obj, replacer);// {"prop1":"Earth","prop2":""}
          console.log(str);

          然后我們使用 Array map() 方法從每個(gè)對象中獲取屬性值。 map() 接受一個(gè)回調(diào)函數(shù),該函數(shù)在每個(gè)數(shù)組元素上調(diào)用以返回一個(gè)轉(zhuǎn)換。

          此回調(diào)使用標(biāo)頭數(shù)組來獲取每個(gè)對象的所有鍵。 再次調(diào)用 map(),它會遍歷每個(gè)鍵,獲取對象中該鍵的對應(yīng)值,并使用 JSON.stringify() 將其轉(zhuǎn)換為字符串。

          這個(gè)對 map() 的內(nèi)部調(diào)用最終會產(chǎn)生一個(gè)數(shù)組,該數(shù)組包含數(shù)組中當(dāng)前對象的所有字符串化屬性值。

          const header = ['color', 'maxSpeed', 'age'];const row = { color: 'red', maxSpeed: 120, age: 2 };const replacer = (key, value) => value ?? '';const rowItem = header.map((fieldName) =>
            JSON.stringify(row[fieldName], replacer)
          );// array of stringified property values
          console.log(rowItem); // [ '"red"', '120', '2' ]

          將對象轉(zhuǎn)換為屬性值數(shù)組后,使用 join() 將數(shù)組轉(zhuǎn)換為 CSV 行。

          ['"red"', '120', '2'].join(',') // -> "red",120,2

          因此,這種轉(zhuǎn)換發(fā)生在 JSON 數(shù)組中的每個(gè)對象上,以生成 CSV 行列表,存儲在我們原始示例中的 rowItems 變量中。

          為了生成最終的 CSV 輸出,我們使用擴(kuò)展語法 (...) 將 headerString 和 rowItems 組合到一個(gè)數(shù)組中。

          const headerString = ['color', 'maxSpeed', 'age'];const rowItems = ['"red",120,2', '"blue",100,3', '"green",130,2'];[headerString, ...rowItems];
          /*
          Output ->
          [
            [ 'color', 'maxSpeed', 'age' ],
            '"red",120,2',
            '"blue",100,3',
            '"green",130,2'
          ]
           */

          然后我們在這個(gè)數(shù)組上調(diào)用 join() 并使用 '\r\n' 字符串作為分隔符,以創(chuàng)建一個(gè)帶有 CSV 標(biāo)題的字符串,并且每個(gè) CSV 行位于單獨(dú)的行中。

          const headerString = ['color', 'maxSpeed', 'age'];const rowItems = ['"red",120,2', '"blue",100,3', '"green",130,2'];console.log([headerString, ...rowItems].join('\r\n'));
          /*
          color,maxSpeed,age
          "red",120,2
          "blue",100,3
          "green",130,2
           */

          關(guān)注七爪網(wǎng),獲取更多APP/小程序/網(wǎng)站源碼資源!


          主站蜘蛛池模板: 国产激情з∠视频一区二区| 精品一区二区三区在线观看视频| 伊人久久一区二区三区无码| 国产福利精品一区二区| 亚洲啪啪综合AV一区| 日韩精品电影一区亚洲| 日韩有码一区二区| 久久精品国产一区二区三区日韩| 一区二区三区久久精品| 欧洲精品无码一区二区三区在线播放| 国产伦精品一区二区三区视频猫咪| 国产精品自在拍一区二区不卡| 99精品国产高清一区二区三区| 久久高清一区二区三区| 久久久久人妻精品一区二区三区| 在线日产精品一区| 国产福利电影一区二区三区,日韩伦理电影在线福 | 青娱乐国产官网极品一区| 怡红院一区二区三区| 国产色综合一区二区三区| 久久久国产精品一区二区18禁 | 国产免费一区二区三区| 狠狠色综合一区二区| 大帝AV在线一区二区三区| 波多野结衣电影区一区二区三区 | 中文字幕精品一区影音先锋 | 99久久精品费精品国产一区二区 | 日韩人妻无码一区二区三区| 麻豆一区二区在我观看| 午夜无码一区二区三区在线观看| 久久福利一区二区| 国产精品久久一区二区三区 | 精品亚洲综合在线第一区| 88国产精品视频一区二区三区| 国产成人综合亚洲一区| 一区二区三区在线|欧| 精品成人一区二区三区免费视频 | 国产一区二区在线| 亚洲一区二区影院| 精品人体无码一区二区三区| 国内精品视频一区二区八戒|