JSON в XML и одна строка для одного объекта в C # - PullRequest
0 голосов
/ 16 мая 2018

Я ищу преобразование из JSON objects в XML 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 голосов
/ 16 мая 2018

С 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>

За дополнительной информацией обратитесь к статье 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>

Отказ от ответственности: я являюсь автором этой библиотеки.

0 голосов
/ 16 мая 2018

Стандартная библиотека преобразования JSON в XML никогда не даст вам именно тот XML, который вы хотите; вам почти всегда захочется следовать за ним с преобразованием этого XML с использованием XSLT.

Альтернатива состоит в том, чтобы вручную создать желаемый XML из исходного JSON.

Оба подхода возможны при использовании XSLT 3.0, который я включаю для иллюстрации, но вы можете использовать тот же подход к проектированию с другими языками.

(a) Если вы выполните стандартное преобразование json в xml с использованием XSLT 3.0, он даст вам структуру 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...