1

在更改 .csproj 文件中的设置的程序中,以下 linq to xml 语句始终返回“对象未设置为对象的实例”:

static void Main(string[] args)
    {
        string rootDir =
            @"e:\path\to\proj\file\foo.csproj";

        var xDoc = XDocument.Load(rootDir);
        var ns = xDoc.Root.Name.Namespace;

        var hasConditions = xDoc.Root.Elements(ns + "PropertyGroup")
            .Where(x => x.Attribute("Condition") != null);

        Console.WriteLine(hasConditions.Count());

        try
        {
            var debugConfig = xDoc.Root.Elements(ns + "PropertyGroup")
                .Where(x => x.Attribute("Condition")
                .Value == " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ");

            Console.WriteLine(debugConfig.Count());
        }
        catch
        {
            Console.WriteLine("doesn't work");
        }
    }

完整的项目文件:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.30703</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{F08E2AEB-A1C2-43F9-A93C-38AF2A99C96A}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>CommunicationSystem.XmlLoading.Common</RootNamespace>
    <AssemblyName>CommunicationSystem.XmlLoading.Common</AssemblyName>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <SccProjectName>SAK</SccProjectName>
    <SccLocalPath>SAK</SccLocalPath>
    <SccAuxPath>SAK</SccAuxPath>
    <SccProvider>SAK</SccProvider>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
    <RunCodeAnalysis>true</RunCodeAnalysis>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
    <RunCodeAnalysis>true</RunCodeAnalysis>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DEV|AnyCPU'">
    <DebugSymbols>true</DebugSymbols>
    <OutputPath>bin\DEV\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <DebugType>full</DebugType>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'SIT|AnyCPU'">
    <DebugSymbols>true</DebugSymbols>
    <OutputPath>bin\SIT\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <DebugType>full</DebugType>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'QA|AnyCPU'">
    <OutputPath>bin\QA\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <Optimize>true</Optimize>
    <DebugType>pdbonly</DebugType>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <ErrorReport>prompt</ErrorReport>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="StorageSystem">
      <HintPath>..\..\..\GlobalDependencies\StorageSystem\beta\StorageSystem.dll</HintPath>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Configuration" />
    <Reference Include="System.Core" />
    <Reference Include="System.Web" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Common\IEnumerableExtensions.cs" />
    <Compile Include="Common\XmlLoaderBase.cs" />
    <Compile Include="Configuration\SchemasConfigurationElement.cs" />
    <Compile Include="Configuration\SettingsConfigurationElement.cs" />
    <Compile Include="Configuration\TConfigurationElementCollection.cs" />
    <Compile Include="Configuration\XmlLoadingConfigurationSection.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="Validation\XValidationResult.cs" />
    <Compile Include="Validation\XValidator.cs" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
   Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>

我的怀疑是它与属性值中的空格有关,但我不能确定....还有其他人面临类似的情况吗?

4

3 回答 3

2

我怀疑这是问题所在:

x.Attribute(ns + "Condition")

确定该属性在命名空间中吗?(与元素名称不同,属性名称不会从 . 继承“默认”命名空间xmlns="..."。)尝试:

x.Attribute("Condition")

编辑:如果问题确实是所有元素上都不存在该属性,那么解决方案比arcain 提出的解决方案更简单。您可以只使用强制转换为字符串:

var debugConfig = xDoc.Root.Elements(ns + "PropertyGroup").Where(x => 
      (string) x.Attribute("Condition") == " [long string here] ");

当调用 null 时,字符串转换将返回null,这是您想要的。

(为混乱的格式道歉 - SO 上的短线使它变得棘手。)

于 2012-06-19T16:59:25.180 回答
1

我不得不执行类似的任务,我遇到了同样的问题。根本原因是该Condition属性可能并不存在于所有PropertyGroup元素上。这是来自我的LINQPad脚本的查询(这是 .Dump() 方法的来源。)

string projFile = @"FileName";

XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
XDocument doc = XDocument.Load(projFile);

var query = from node in doc.Root.Descendants(ns + "PropertyGroup")
        where node.Attribute("Condition") != null // this fixed the issue
        && node.Attribute("Condition").Value.IndexOf(
                "'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'",
                StringComparison.OrdinalIgnoreCase) >= 0
        select node;

query.Dump();
于 2012-06-19T17:16:26.500 回答
0

您已经有了答案,但我使用这个 xml 库和这个简单的 XPath 解决了它:

XElement root = XElement.Load(file);
XElement node = root.XPathElement("//PropertyGroup[@Condition={0}]",
                " '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ");
于 2012-06-19T17:23:39.973 回答