简体   繁体   English

使用MSBuild将多个JSON文件合并为一个JSON文件

[英]Merge multiple JSON files into one JSON file using MSBuild

In my ASP.NET MVC Web project, I have got a number of JSON files lying around. 在我的ASP.NET MVC Web项目中,我得到了很多JSON文件。

File1.json

{
   "manage_employees_section_title": 
    {
        "value": "Manage employees",
        "description": "The mange employees section title"
    }
}

File2.json

{
   "manage_operations_section_title": 
    {
        "value": "Manage operations
        "description": "The mange operations section title"
    }
}

I need to as part of my build process get all my JSONs and merge into one single file. 作为构建过程的一部分,我需要获取所有JSONs并合并到一个文件中。

I have used MSBuild like this. 我已经这样使用过MSBuild。

<Target Name="ConcatenateJsFiles">
   <ItemGroup>
     <ConcatFiles Include="Application\**\resource-content*.json"/>
   </ItemGroup>

   <ReadLinesFromFile File="%(ConcatFiles.Identity)">
     <Output TaskParameter="Lines" ItemName="ConcatLines"/>
   </ReadLinesFromFile>

   <WriteLinesToFile File="Infrastructure\Content\Store\ContentStore.json" Lines="@(ConcatLines)" Overwrite="true" />
</Target>

And this is what I got... 这就是我得到的...

Concat.json

//What I got
{
   "manage_employees_section_title": 
    {
        "value": "Manage employees",
        "description": "The mange employees section title"
    }
}
{
   "manage_operations_section_title": 
    {
        "value": "Manage operations
        "description": "The mange operations section title"
    }
}

Even though I have achieved my goal of concatenation, what I really want is to merge all JSON files into one JSON object. 即使我实现了串联的目标,但我真正想要的是将所有JSON文件合并到一个JSON对象中。

//What I really want
{
   "manage_employees_section_title": 
    {
        "value": "Manage employees",
        "description": "The mange employees section title"
    },
   "manage_operations_section_title": 
    {
        "value": "Manage operations
        "description": "The mange operations section title"
    }
}

How can I achieve this as part of my build process with Visual Studio. 如何在使用Visual Studio构建过程中实现这一目标。

Many thanks in advance guys.. 非常感谢大家..

It was interesting task to obtain the result using MSBuild functionality only... To be honest, creating additional C# application for this goal is better approach. 仅使用MSBuild功能获得结果是一项有趣的任务。老实说,为此目标创建其他C#应用程序是更好的方法。 But I was able to do it with MSBuild as well: 但是我也能够通过MSBuild做到这一点:

<Project ToolsVersion="12.0" DefaultTargets="ConcatenateJsFiles" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
  <Target Name="ConcatenateJsFiles">
    <ItemGroup>
      <ConcatFiles Include="Application\**\resource-content*.json"/>
    </ItemGroup>

    <ItemGroup>
      <!-- Read file content (with spaces preserving), remove trailing { and } -->
      <ContentLines Include="$([System.IO.File]::ReadAllText('%(ConcatFiles.Identity)').Remove($([MSBuild]::Subtract($([System.IO.File]::ReadAllText('%(ConcatFiles.Identity)').Length), 1)), 1).Remove(0, 1))"/>
      <!-- Create resulting file with trailing { and } -->
      <FileContent Include="{"/>
      <FileContent Include="@(ContentLines, ',%0a')"/>
      <FileContent Include="}"/>
    </ItemGroup>

    <WriteLinesToFile File="ContentStore.json" Lines="@(FileContent)" Overwrite="true" />
  </Target>
</Project>

As a result you'll have the following file: 结果,您将拥有以下文件:

{
"manage_employees_section_title": 
    {
        "value": "Manage employees",
        "description": "The mange employees section title"
    },
"manage_operations_section_title": 
    {
        "value": "Manage operations",
        "description": "The mange operations section title"
    }
}

This approach is not flexible enough, for example it requires trailing braces to be located at the first and at the last positions of source files. 这种方法不够灵活,例如,它要求在源文件的第一个和最后一个位置放置尾括号。 Anyway, it is enough to demonstrate how to do it with MBSuild only. 无论如何,仅演示如何使用MBSuild就足够了。

One thing you can do is create a small C# application and add that to your pre-build process: 您可以做的一件事是创建一个小型C#应用程序,并将其添加到预构建过程中:

Create an application that takes an argument for a directory. 创建一个使用目录参数的应用程序。 You can use the .NET JSON parsing classes in the System.Runtime.Serialization.DataContractJsonSerializer to get objects from each of your JSON files. 您可以在System.Runtime.Serialization.DataContractJsonSerializer中使用.NET JSON解析类,以从每个JSON文件中获取对象。 Based on your description, it sounds like you can already parse the objects successfully. 根据您的描述,听起来您已经可以成功解析对象。

Put all of the objects into a collection and serialize the output into a single file. 将所有对象放入集合中,并将输出序列化为单个文件。 When running multiple instances of VS you may run into problems with file access, so name your file uniquely. 当运行多个VS实例时,您可能会遇到文件访问问题,因此请唯一命名文件。

Add your application to the Properties > Build Events > Pre-build Event Command Line in visual studio. 将您的应用程序添加到Visual Studio中的“ 属性”>“构建事件”>“预构建事件命令行” You can determine the working directory at build time using some of the build macros included in visual studio. 您可以使用Visual Studio中包含的一些构建宏在构建时确定工作目录。 For example, MyApp.exe $(ProjectDir) would pass the argument of the project directory, which would be decided at build time should you have multiple areas. 例如, MyApp.exe $(ProjectDir)将传递项目目录的参数,如果您有多个区域,则将在构建时确定该参数。

-MF -MF

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM