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

时间:2015-03-11 17:45:25

标签: json visual-studio msbuild build-process csproj

在我的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"
    }
}

我需要在构建过程中获取所有JSONs并合并到一个文件中。

我已经像这样使用了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>

这就是我得到的......

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"
    }
}

即使我已达到连接目标,我真正想要的是将所有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"
    }
}

如何使用Visual Studio将其作为构建过程的一部分来实现。

非常感谢先生......

2 个答案:

答案 0 :(得分:1)

仅使用MSBuild功能获取结果是一项有趣的任务...老实说,为此目标创建额外的C#应用​​程序是更好的方法。但我也可以用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>

因此,您将拥有以下文件:

{
"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"
    }
}

这种方法不够灵活,例如它需要将尾部括号放在源文件的第一个和最后一个位置。无论如何,仅仅演示如何使用MBSuild就足够了。

答案 1 :(得分:0)

您可以做的一件事是创建一个小型C#应用程序并将其添加到预构建过程中:

创建一个为目录提取参数的应用程序。您可以使用 System.Runtime.Serialization.DataContractJsonSerializer 中的.NET JSON解析类从每个JSON文件中获取对象。根据您的描述,听起来您已经可以成功解析对象。

将所有对象放入集合中,并将输出序列化为单个文件。运行VS的多个实例时,您可能会遇到文件访问问题,因此请唯一地命名您的文件。

将您的应用添加到属性&gt;构建活动&gt; Visual Studio中的预构建事件命令行。您可以使用visual studio中包含的一些构建宏在构建时确定工作目录。例如, MyApp.exe $(ProjectDir)会传递项目目录的参数,如果您有多个区域,则会在构建时决定。

-MF