C# Объект для Json до Xml, как создать элемент xml для элементов массива - PullRequest
0 голосов
/ 20 января 2020

Сначала я конвертирую Объект в json, а затем преобразую json в xml. Мне нужно сделать это, чтобы сгенерировать некоторые свойства как атрибут xml вместо элементов. Все работает, как и ожидалось, за исключением того, что я не смог создать отдельный элемент xml для каждого элемента.

C# код:

string json = JsonConvert.SerializeObject(myObj);
XmlDocument xdoc = JsonConvert.DeserializeXmlNode(json, "root");

Сгенерировано json:

{
  "header": "myheader",
  "transaction": {
    "date": "2019-09-24",
    "items": [
      {
        "number": "123",
        "unit": "EA",
        "qty": 6
      },
      {
        "number": "456",
        "unit": "CS",
        "qty": 4
      }
    ]
  }
}

C# классы:

public class Item
{
    [JsonProperty("@number")]
    public string number { get; set; }
    [JsonProperty("@unit")]
    public string unit { get; set; }
    [JsonProperty("@qty")]
    public int qty { get; set; }
}

public class Transaction
{
    [JsonProperty("@date")]
    public string date { get; set; }
    public List<Item> items { get; set; }
}

public class Root
{
    public string header { get; set; }
    public Transaction transaction { get; set; }
}

Генерируемый (не желательный) вывод:

<root>
    <header>string</header>
    <transaction date="string">
        <items number="string" unit="string" qty="0"/>
        <items number="string" unit="string" qty="0"/>
    </transaction>
</root>

Ожидаемый вывод:

<root>
    <header>string</header>
    <transaction date="string">
        <items>
            <item number="string" unit="string" qty="0"/>
            <item number="string" unit="string" qty="0"/>
        </items>
    </transaction>
</root>

1 Ответ

0 голосов
/ 21 января 2020

Следовали инструкциям на этой ссылке , рекомендованной @Abhineet Chaudhary. Работает как положено.

var jObject = JObject.Parse(json);
jObject.SelectToken("transaction").SelectTokens("items").WrapWithObjects("item");
var finalXml = jObject.ToXElement("root", false);

public static class JsonExtensions
{
    public static void WrapWithObjects(this IEnumerable<JToken> values, string name)
    {
        foreach (var value in values.ToList())
        {
            var newParent = new JObject();
            if (value.Parent != null)
                value.Replace(newParent);
            newParent[name] = value;
        }
    }

    public static XElement ToXElement(this JObject obj, string deserializeRootElementName = null, bool writeArrayAttribute = false)
    {
        if (obj == null)
            return null;
        using (var reader = obj.CreateReader())
            return JsonExtensions.DeserializeXElement(reader, deserializeRootElementName, writeArrayAttribute);
    }

    static XElement DeserializeXElement(JsonReader reader, string deserializeRootElementName, bool writeArrayAttribute)
    {
        var converter = new Newtonsoft.Json.Converters.XmlNodeConverter() { DeserializeRootElementName = deserializeRootElementName, WriteArrayAttribute = writeArrayAttribute };
        var jsonSerializer = JsonSerializer.CreateDefault(new JsonSerializerSettings { Converters = new JsonConverter[] { converter } });
        return jsonSerializer.Deserialize<XElement>(reader);
    }
}
...