JSON到XML,以及C#中单个对象的一行

时间:2018-05-16 02:53:03

标签: c# arrays json xml xml-parsing

我正在寻找每个对象从JSON objectsXML single row的转换。现在,我能够转换为XML,但这不是我想要的。有人可以帮助我吗?另外,我不需要一些字段。以下是JSON and preferred XML structure

JSON示例

{
   "paging": {
      "limit": 100,
      "total": 1394,
      "next": "Mg=="
   },
   "data": [
      {
         "mmsi": 538006090,
         "imo": 9700665,
         "last_known_position": {
            "timestamp": "2017-12-18T20:24:27+00:00",
            "geometry": {
               "type": "Point",
               "coordinates": [
                  60.87363,
                  -13.02203
               ]
            }
         }
      },
      {
         "mmsi": 527555481,
         "imo": 970000,
         "last_known_position": {
            "timestamp": "2017-12-18T20:24:27+00:00",
            "geometry": {
               "type": "Point",
               "coordinates": [
                  4.57883,
                  3.76899
               ]
            }
         }
      }
   ]
}

我想要的XML

<vessel>
     <row mmsi="538006090" imo="9700665" lat="60.87363" lon="-13.02203"/>
     <row mmsi="527555481" imo="970000" lat="4.57883" lon="3.76899"/>
</vessel>

谢谢

2 个答案:

答案 0 :(得分:0)

标准的JSON-to-XML转换库永远不会为您提供所需的XML;您几乎总是希望使用XSLT对XML进行转换。

另一种方法是从原始JSON手工构造您想要的XML。

这两种方法都可以使用XSLT 3.0,我将其用于说明目的,但您可以使用与其他语言相同的设计方法。

(a)如果使用XSLT 3.0进行标准的json-to-xml转换,它将为您提供如下的XML结构:

<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.w3.org/2005/xpath-functions">
   <map key="paging">
      <number key="limit">100</number>
      <number key="total">1394</number>
      <string key="next">Mg==</string>
   </map>
   <array key="data">
      <map>
         <number key="mmsi">538006090</number>
         <number key="imo">9700665</number>
         <map key="last_known_position">
            <string key="timestamp">2017-12-18T20:24:27+00:00</string>
            <map key="geometry">
               <string key="type">Point</string>
               <array key="coordinates">
                  <number>60.87363</number>
                  <number>-13.02203</number>
               </array>
            </map>
         </map>
      </map>
      <map>
         <number key="mmsi">527555481</number>
         <number key="imo">970000</number>
         <map key="last_known_position">
            <string key="timestamp">2017-12-18T20:24:27+00:00</string>
            <map key="geometry">
               <string key="type">Point</string>
               <array key="coordinates">
                  <number>4.57883</number>
                  <number>3.76899</number>
               </array>
            </map>
         </map>
      </map>
   </array>
</map>

然后您可以使用以下方法将其转换为所需的输出:

<xsl:template name="postprocess" xpath-default-namespace=""http://www.w3.org/2005/xpath-functions">
  <vessel>
    <xsl:for-each select=".//map[number[@key='mmsi']]">
       <row mmsi="{*[@key='mmsi']}" 
            imo="*[@key='imo']" 
            lat="{.//*[@key='coordinates']/number[1]}" 
            lon="{.//*[@key='coordinates']/number[1]}"/>
    </xsl:for-each>
  </vessel>
</xsl:template>

(b)或者,也许在这种情况下更容易,您可以选择所需的JSON部分并直接构建XML:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all"
  version="3.0">

  <xsl:template name="xsl:initial-template">
    <vessel>
      <xsl:for-each select="json-doc('test.json')?data?*">
        <xsl:variable name="coords" select="?last_known_position?geometry?coordinates"/>
        <row mmsi="{xs:integer(?mmsi)}" imo="{xs:integer(?imo)}" lat="{$coords?1}" lon="{$coords?2}"/>
      </xsl:for-each>
    </vessel>
  </xsl:template>  

</xsl:transform>

答案 1 :(得分:0)

使用Cinchoo ETL - 一个开源库,您可以使用几行代码轻松完成转换

string json = @"{
    ""paging"": {

        ""limit"": 100,
        ""total"": 1394,
        ""next"": ""Mg==""
    },
    ""data"": [
        {
            ""mmsi"": 538006090,
            ""imo"": 9700665,
            ""last_known_position"": {
            ""timestamp"": ""2017-12-18T20:24:27+00:00"",
            ""geometry"": {
                ""type"": ""Point"",
                ""coordinates"": [
                    60.87363,
                    -13.02203
                ]
    }
}
        },
        {
            ""mmsi"": 527555481,
            ""imo"": 970000,
            ""last_known_position"": {
            ""timestamp"": ""2017-12-18T20:24:27+00:00"",
            ""geometry"": {
                ""type"": ""Point"",
                ""coordinates"": [
                    4.57883,
                    3.76899
                ]
            }
            }
        }
    ]
}
";
StringBuilder sb = new StringBuilder();
using (var p = ChoJSONReader.LoadText(json)
    .WithJSONPath("$..data")
    )
{
    using (var w = new ChoXmlWriter(sb)
        .Configure(c => c.RootName = "vessel")
        .Configure(c => c.NodeName = "row")
        )
    {
        w.Write(p.Select(r => new { _mmsi = r.mmsi, _imo = r.imo, _lat = r.last_known_position.geometry.coordinates[0], _lon = r.last_known_position.geometry.coordinates[1] }));
    }
}
Console.WriteLine(sb.ToString());

输出:

<vessel>
  <row mmsi="538006090" imo="9700665" lat="60.87363" lon="-13.02203" />
  <row mmsi="527555481" imo="970000" lat="4.57883" lon="3.76899" />
</vessel>

Checkout CodeProject文章提供了一些额外的帮助。

<强>更新

要处理特殊的空值条件,可以按如下所示编写

string json = @"{
    ""paging"": {

        ""limit"": 100,
        ""total"": 1394,
        ""next"": ""Mg==""
    },
    ""data"": [
        {
            ""mmsi"": 538006090,
            ""imo"": 9700665,
            ""last_known_position"": {
            ""timestamp"": ""2017-12-18T20:24:27+00:00"",
            ""geometry"": {
                ""type"": ""Point"",
                ""coordinates"": [
                    60.87363,
                    -13.02203
                ]
    }
}
        },
        {
            ""mmsi"": 527555481,
            ""imo"": null,
            ""last_known_position"": {
            ""timestamp"": ""2017-12-18T20:24:27+00:00"",
            ""geometry"": {
                ""type"": ""Point"",
                ""coordinates"": [
                    4.57883,
                    3.76899
                ]
            }
            }
        }
    ]
}
";
StringBuilder sb = new StringBuilder();
using (var p = ChoJSONReader.LoadText(json)
    .WithJSONPath("$..data")
    )
{
    using (var w = new ChoXmlWriter(sb)
        .Configure(c => c.RootName = "vessel")
        .Configure(c => c.NodeName = "row")
        )
    {
        w.Write(p.Select(r => new { _mmsi = r.mmsi, _imo = r.imo == null ? "null" : r.imo, _lat = r.last_known_position.geometry.coordinates[0], _lon = r.last_known_position.geometry.coordinates[1] }));
    }
}
Console.WriteLine(sb.ToString());

输出:

<vessel>
  <row mmsi="538006090" imo="9700665" lat="60.87363" lon="-13.02203" />
  <row mmsi="527555481" imo="null" lat="4.57883" lon="3.76899" />
</vessel>

免责声明:我是这个图书馆的作者。