如何使用Powershell和XPath从xml中提取值,并根据文件的值搜索(如果存在)

时间:2018-05-18 14:10:09

标签: xml windows powershell xpath msbuild

  

问题:   我有这个XML数据:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <ItemGroup>
    <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\..\..\..\..\packages\EntityFramework.6.1.2\lib\net45\EntityFramework.dll</HintPath>
    </Reference>
    <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\..\..\..\..\packages\EntityFramework.6.1.2\lib\net45\EntityFramework.SqlServer.dll</HintPath>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.ComponentModel.DataAnnotations" />
  </ItemGroup>
</Project>
  

我必须在Powershell中编写一个函数,它检查是否所有引用都在   项目是有效的(即所有引用的程序集都存在;你可以   在块内看到它们)。输出两者:全部   带有无效引用的项目和程序集的无效路径。

到目前为止,我已经尝试过这个:

[xml]$results = Get-Content path-to-file/MigratorConsole.csproj

$fianl += $results.Project.ItemGroup.Reference | %{$_.HintPath} | select-object -unique

$fianl
$fianl.length

这给了我&#34; HintPath&#34;价值,但我无法得到匹配&#34;项目&#34;用于检查HintPath错误或文件不存在的项目的值。

请帮忙!

1 个答案:

答案 0 :(得分:0)

将XML填充到变量中......

[xml]$foo = @'
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <ItemGroup>
    <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>c:\packages\EntityFramework.6.1.2\lib\net45\EntityFramework.dll</HintPath>
    </Reference>
    <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>c:\packages\EntityFramework.6.1.2\lib\net45\EntityFramework.SqlServer.dll</HintPath>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.ComponentModel.DataAnnotations" />
  </ItemGroup>
</Project>
'@

我遍历每个项目元素。对于每个项目,我都会提取参考文献。如果我找到一个无效的引用(路径不存在),我会回吐一条消息,说明无效路径并注意到该项目:

foreach ($project in $foo.project) {
    foreach ($reference in $project.ItemGroup.Reference) {
        if ([string]::IsNullOrEmpty($reference.HintPath) -eq $false) {
            if ( $(Test-Path -Path $reference.HintPath) -eq $false ) {
                Write-Output "Bad Path in $(${project}.Import.GetAttribute('Project'))"
            }
        }
    }
}

我确定这不是您想要的信息。这种方法与我想表达的方式相似。我使用多个循环。一个是你关心的第一个实体:项目。另一个是第二个:参考路径。希望这是有道理的。

祝你好运, A -