[英]C#/.Net -Fast way to Parse XML / XML -> Json
我是 XML 新手,因為現在我只使用過 Json :( 我有一個 XML 文件,如下所示:
<AdapterCards>
<cards type="MCS">
<card>
<id>id1</id>
<description>desc1</description>
<mccode>code1</mccode>
</card>
<card>
<id>id2</id>
<description>desc2</description>
<mccode>code2</mccode>
</card>
</cards>
<cards type="MCM">
<card>
<id>id3</id>
<description>desc3</description>
<mccode>code3</mccode>
</card>
<card>
<id>id4</id>
<description>desc4</description>
<mccode>code4</mccode>
</card>
</cards>
<cards type="F"/>
<cards type="B"/>
</AdapterCards>
我想將它解析為一個 json 字符串,它應該是這樣的:
{[{'type': 'mcs', 'id': 'id1', 'description': 'desc1', 'mccode': 'code1'},
{'type': 'mcs', 'id': 'id2', 'description': 'desc2', 'mccode': 'code2'},
{'type': 'mcm', 'id': 'id3', 'description': 'desc3', 'mccode': 'code3'},
{'type': 'mcm', 'id': 'id4', 'description': 'desc4', 'mccode': 'code4'}
]}
我的問題是我根本沒有使用過 XML(是的,我很慚愧)。 你能給我一些關於如何快速解析 xml 的線索嗎(我把它放在一個流上,我把它上傳到服務器上)。 我已經搜索了一些 XML 到 Json 的轉換器,但不可能滿足我的需要,因為我需要一種“特殊”格式。
謝謝你的回答:)! 我正在使用 C#。
我最近不得不自己為同一類型的事情編寫一個定制的解決方案。 我用 XSLT 做到了,使用XslCompiledTransform
類來運行 XML 輸入和輸出 JSON。
這需要一些工作,但應該可以幫助您了解基礎知識(它是從我所做的工作中復制粘貼的,更改為幾乎適合您的需求):
適配器卡.XML
<AdapterCards>
<cards type="MCS">
<card>
<id>id1</id>
<description>desc1</description>
<mccode>code1</mccode>
</card>
<card>
<id>id2</id>
<description>desc2</description>
<mccode>code2</mccode>
</card>
</cards>
<cards type="MCM">
<card>
<id>id3</id>
<description>desc3</description>
<mccode>code3</mccode>
</card>
<card>
<id>id4</id>
<description>desc4</description>
<mccode>code4</mccode>
</card>
</cards>
<cards type="F"/>
<cards type="B"/>
</AdapterCards>
適配卡.XSL
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="no" omit-xml-declaration="yes" method="text" encoding="UTF-8" media-type="text/x-json" />
<xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
<!-- Main template for escaping strings; used by above template and for object-properties
Responsibilities: placed quotes around string, and chain up to next filter, escape-bs-string -->
<xsl:template name="escape-string">
<xsl:param name="s"/>
<xsl:text>"</xsl:text>
<xsl:call-template name="escape-bs-string">
<xsl:with-param name="s" select="$s"/>
</xsl:call-template>
<xsl:text>"</xsl:text>
</xsl:template>
<!-- Escape the backslash (\) before everything else. -->
<xsl:template name="escape-bs-string">
<xsl:param name="s"/>
<xsl:choose>
<xsl:when test="contains($s,'\')">
<xsl:call-template name="escape-quot-string">
<xsl:with-param name="s" select="concat(substring-before($s,'\'),'\\')"/>
</xsl:call-template>
<xsl:call-template name="escape-bs-string">
<xsl:with-param name="s" select="substring-after($s,'\')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="escape-quot-string">
<xsl:with-param name="s" select="$s"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Escape the double quote ("). -->
<xsl:template name="escape-quot-string">
<xsl:param name="s"/>
<xsl:choose>
<xsl:when test="contains($s,'"')">
<xsl:call-template name="encode-string">
<xsl:with-param name="s" select="concat(substring-before($s,'"'),'\"')"/>
</xsl:call-template>
<xsl:call-template name="escape-quot-string">
<xsl:with-param name="s" select="substring-after($s,'"')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="encode-string">
<xsl:with-param name="s" select="$s"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Replace tab, line feed and/or carriage return by its matching escape code. Can't escape backslash
or double quote here, because they don't replace characters (� becomes \t), but they prefix
characters (\ becomes \\). Besides, backslash should be seperate anyway, because it should be
processed first. This function can't do that. -->
<xsl:template name="encode-string">
<xsl:param name="s"/>
<xsl:choose>
<!-- tab -->
<xsl:when test="contains($s,'	')">
<xsl:call-template name="encode-string">
<xsl:with-param name="s" select="concat(substring-before($s,'	'),'\t',substring-after($s,'	'))"/>
</xsl:call-template>
</xsl:when>
<!-- line feed -->
<xsl:when test="contains($s,'
')">
<xsl:call-template name="encode-string">
<xsl:with-param name="s" select="concat(substring-before($s,'
'),'\n',substring-after($s,'
'))"/>
</xsl:call-template>
</xsl:when>
<!-- carriage return -->
<xsl:when test="contains($s,'
')">
<xsl:call-template name="encode-string">
<xsl:with-param name="s" select="concat(substring-before($s,'
'),'\r',substring-after($s,'
'))"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$s"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="card">
<xsl:text>{</xsl:text>
<xsl:text>"type":</xsl:text>
<xsl:call-template name="escape-string">
<xsl:with-param name="s" select="translate(../@type, $uppercase, $smallcase)"/>
</xsl:call-template>
<xsl:text>,"id":</xsl:text>
<xsl:call-template name="escape-string">
<xsl:with-param name="s" select="id"/>
</xsl:call-template>
<xsl:text>,"description":</xsl:text>
<xsl:call-template name="escape-string">
<xsl:with-param name="s" select="description"/>
</xsl:call-template>
<xsl:text>,"mccode":</xsl:text>
<xsl:call-template name="escape-string">
<xsl:with-param name="s" select="mccode"/>
</xsl:call-template>
<xsl:if test="following::card">},</xsl:if>
<xsl:if test="not(following::card)">}</xsl:if>
</xsl:template>
<xsl:template match="/AdapterCards">
<xsl:text>{[</xsl:text>
<xsl:apply-templates select="cards/card" />
<xsl:text>]}</xsl:text>
</xsl:template>
</xsl:stylesheet>
C#
// Load XML document
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("AdapterCards.XML");
// Transform the XML into JSON
XslCompiledTransform transformer = new XslCompiledTransform();
using (var xslStylesheetFile = File.Open("AdapterCards.XSL", FileMode.Open))
{
using (var xmlReader = new XmlTextReader(xslStylesheetFile))
{
transformer.Load(xmlReader);
}
}
var sourceNavigator = xmlDoc.CreateNavigator();
using (MemoryStream ms = new MemoryStream())
{
transformer.Transform(sourceNavigator, null, ms);
ms.Position = 0;
using (var sr = new StreamReader(ms))
{
return sr.ReadToEnd(); // <-- this is your JSON
}
}
我在 Notepad++ 中執行了上述 XSL 並得到以下結果:
{[{"type":"mcs","id":"id1","description":"desc1","mccode":"code1"},
{"type":"mcs","id":"id2","description":"desc2","mccode":"code2"},
{"type":"mcm","id":"id3","description":"desc3","mccode":"code3"},
{"type":"mcm","id":"id4","description":"desc4","mccode":"code4"}]}
如您所見,在需要的地方缺少逗號。 但它幾乎就在那里!!
更新了 XSL 和現在在正確位置使用逗號的輸出。 接下來要解決的是“類型”的情況。 我認為您可能需要使用 XSL 2.0 來訪問xpath 函數fn:lower-case()
。
EDIT3 :Done-case 現在在這個答案的幫助下被轉換為更低。
參考:
使用包含輔助方法的 JsonConvert 類用於此精確目的:
// To convert an XML node contained in string xml into a JSON string
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(doc);
// To convert JSON text contained in string json into an XML node
XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(json);
這是使用Cinchoo ETL (一種開源庫)將 xml 轉換為 json 文件的另一種簡單方法
using (var r = new ChoXmlReader("*** Xml file path ***")
.WithXPath("//cards")
)
{
using (var w = new ChoJSONWriter("*** Json file path ***")
)
w.Write(r.SelectMany(r1 => ((dynamic[])r1.cards??new dynamic[]{}).Select(c => new { r1.type, c.id, c.description, c.mccode })));
}
小提琴示例: https : //dotnetfiddle.net/Yzcaiw
XDocument xDoc = XDocument.Load(queryURL);
var x1 = from el in xDoc.Root.Descendants("results").Descendants("div").Descendants("div").Descendants("span").Attributes("class")
where el.Value == "pr"
select el.Parent.Value;
stockFeed.Price = Decimal.Parse(x1.First().ToString());
LINQ 是提取數據的最佳方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.