c# - 如何使用XDocument读取csproj文件?

标签 c# .net xml linq linq-to-xml

我想对 csproj 文件进行一些路径更改以配置源代码管理。我没有手动完成,而是想遍历 csproj 文件并在每个 csproj 中使用 Linq-to-Xml 根据需要更改构建和引用路径。

所以我环顾四周,目前正在尝试使用:

public void Read(string  fileName)
{
    XDocument doc = XDocument.Load(fileName);

    foreach (XElement el in doc.Root.Elements())
    {
        Console.WriteLine("{0} {1}", el.Name, el.Attribute("id").Value);
        Console.WriteLine("  Attributes:");
        foreach (XAttribute attr in el.Attributes())
            Console.WriteLine("    {0}", attr);
        Console.WriteLine("  Elements:");

        foreach (XElement element in el.Elements())
            Console.WriteLine("    {0}: {1}", element.Name, element.Value);
    }
}

根据这个 SO 问题的公认答案 xml-parsing-read-a-simple-xml-file-and-retrieve-values . 然而当行

foreach (XElement el in doc.Root.Elements())

已处理 我在调用 Elements 时收到空引用错误。我也试过调用节点、后代等,但它们都是空的。医生。 doc.Root 确实返回了 proj 文件中的所有内容(顶部的命名空间行除外),所以有些东西我只是没有正确地走它。

那我做错了什么?我希望 Elements 返回一组 XML 片段,我可以遍历或过滤以提取我想要的片段,即

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

更新:

所以这是一个 csproj 示例:

<?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>{2CCAB46D-7A7C-4C65-B6D2-DC2D4049FCD9}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>Basd.Core</RootNamespace>
    <AssemblyName>Basd.Core</AssemblyName>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <TargetFrameworkProfile>
    </TargetFrameworkProfile>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>..\..\Basd.Bin\AnyCPU\Release\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>..\..\Basd.Bin\AnyCPU\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
    <PlatformTarget>x86</PlatformTarget>
    <OutputPath>..\..\Basd.Bin\x86\Debug\</OutputPath>
    <DebugType>full</DebugType>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <OutputPath>..\..\Basd.Bin\AnyCPU\Release\</OutputPath>
    <DefineConstants>
    </DefineConstants>
    <DebugType>pdbonly</DebugType>
    <DebugSymbols>true</DebugSymbols>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="Microsoft.VisualBasic" />
    <Reference Include="System" />
    <Reference Include="System.Configuration" />
    <Reference Include="System.Core" />
    <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="Activation\ActivationExtensions.cs" />
    <Compile Include="Activation\ActivationMetaDataList.cs" />
    <Compile Include="Activation\ActivationProviderFactory.cs" />
    <Compile Include="Activation\ActivationMetaDataConfigurationProvider.cs" />
    <Compile Include="Activation\ActivationMetaDataConfigurationProviderSection.cs" />
    <Compile Include="Activation\ActivationMetaDataProvider.cs" />
    <Compile Include="Activation\IActivationMetaData.cs" />
    <Compile Include="Activation\ActivationMetaData.cs" />
    <Compile Include="Activation\IActivationMetaDataProvider.cs" />
    <Compile Include="Collections\DomainList.cs" />
    <Compile Include="DateTime\GenerationDateRange.cs" />
    <Compile Include="DateTime\DateBlitterExtensions.cs" />
    <Compile Include="Dto\DTOStub.generic.cs" />
    <Compile Include="Dto\Tabulation.cs" />
    <Compile Include="Dto\TabulatedItem.cs" />
    <Compile Include="Dto\DTOStub.cs" />
    <Compile Include="Environment\EnvironmentContext.cs" />
    <Compile Include="Events\Delegates.cs" />
    <Compile Include="Activation\ActivationHelper.cs" />
    <Compile Include="Helpers\ObjectScrubber.cs" />
    <Compile Include="Helpers\SmtpHelper.cs" />
    <Compile Include="Interfaces\INameHolder.cs" />
    <Compile Include="Interfaces\IFrame.cs" />
    <Compile Include="Events\FrameEventArgs.cs" />
    <Compile Include="Events\PayloadedEventArgs.cs" />
    <Compile Include="Helpers\DateHelper.cs" />
    <Compile Include="Helpers\EnumerableDataSources.cs" />
    <Compile Include="Helpers\EnumHelper.cs" />
    <Compile Include="Helpers\StringsHelper.cs" />
    <Compile Include="Interfaces\IIndexable.cs" />
    <Compile Include="Interfaces\INameable.cs" />
    <Compile Include="Collections\NamedList.cs" />
    <Compile Include="Interfaces\IText.cs" />
    <Compile Include="Events\KeyChangedEventArgs.cs" />
    <Compile Include="DateTime\DateRange.cs" />
    <Compile Include="DateTime\EntityDateRange.cs">
      <SubType>Code</SubType>
    </Compile>
    <Compile Include="DateTime\IMinimumBoundedDateRange.cs" />
    <Compile Include="DateTime\IDateRange.cs" />
    <Compile Include="Enumerations.cs" />
    <Compile Include="DateTime\IEntityDateRange.cs" />
    <Compile Include="Interfaces\IUserNotifier.cs" />
    <Compile Include="Collections\IXtendedEnumerable.cs" />
    <Compile Include="Membership.cs" />
    <Compile Include="DateTime\MinimumBoundedDateRange.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="Properties\Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <Compile Include="SeriesCube.cs" />
    <Compile Include="Collections\XList.cs" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include="Compression\" />
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    </EmbeddedResource>
  </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>

从设置了断点的中间窗口

 foreach (XElement el in doc.Root.Elements())

?doc.Root.ToString(); "<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n  <PropertyGroup>\r\n    <Configuration Condition=\" '$(Configuration)'
== '' \">Debug</Configuration>\r\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\r\n    <ProductVersion>8.0.30703</ProductVersion>\r\n    <SchemaVersion>2.0</SchemaVersion>\r\n    <ProjectGuid>{2CCAB46D-7A7C-4C65-B6D2-DC2D4049FCD9}</ProjectGuid>\r\n  <OutputType>Library</OutputType>\r\n    <AppDesignerFolder>Properties</AppDesignerFolder>\r\n    <RootNamespace>Basd.Core</RootNamespace>\r\n    <AssemblyName>Basd.Core</AssemblyName>\r\n    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>\r\n    <FileAlignment>512</FileAlignment>\r\n    <TargetFrameworkProfile></TargetFrameworkProfile>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <DebugType>full</DebugType>\r\n    <Optimize>false</Optim ize>\r\n    <OutputPath>..\\..\\Basd.Bin\\AnyCPU\\Release\\</OutputPath>\r\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n    <PlatformTarget>AnyCPU</PlatformTarget>\r\n    <Prefer32Bit>false</Prefer32Bit>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\r\n    <DebugType>pdbonly</DebugType>\r\n    <Optimize>true</Optimize>\r\n    <OutputPath>..\\..\\Basd.Bin\\AnyCPU\\Release\\</OutputPath>\r\n    <DefineConstants>TRACE</DefineConstants>\r\n    <ErrorReport>prompt</ErrorReport>\r\n    <WarningLevel>4</WarningLevel>\r\n    <PlatformTarget>AnyCPU</PlatformTarget>\r\n    <Prefer32Bit>false</Prefer32Bit>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Debug|x86'\">\r\n    <PlatformTarget>x86</PlatformTarget>\r\n    <OutputPath>..\\..\\Basd.Bin\\x86\\Debug\\</OutputPath>\r\n    <DebugType>full</DebugType>\r\n    <Prefer32Bit>fals e</Prefer32Bit>\r\n  </PropertyGroup>\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Release|x86'\">\r\n    <PlatformTarget>AnyCPU</PlatformTarget>\r\n    <OutputPath>..\\..\\Basd.Bin\\AnyCPU\\Release\\</OutputPath>\r\n    <DefineConstants></DefineConstants>\r\n    <DebugType>pdbonly</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <Prefer32Bit>false</Prefer32Bit>\r\n  </PropertyGroup>\r\n  <ItemGroup>\r\n    <Reference Include=\"Microsoft.VisualBasic\" />\r\n <Reference Include=\"System\" />\r\n    <Reference Include=\"System.Configuration\" />\r\n    <Reference Include=\"System.Core\" />\r\n    <Reference Include=\"System.Xml.Linq\" />\r\n    <Reference Include=\"System.Data.DataSetExtensions\" />\r\n    <Reference Include=\"Microsoft.CSharp\" />\r\n    <Reference Include=\"System.Data\" />\r\n    <Reference Include=\"System.Xml\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Compile Include=\"Activation\\ActivationExtensions.cs\" />\r\n    <Compile Include=\"Activation\\Act ivationMetaDataList.cs\" />\r\n    <Compile Include=\"Activation\\ActivationProviderFactory.cs\" />\r\n    <Compile Include=\"Activation\\ActivationMetaDataConfigurationProvider.cs\" />\r\n    <Compile Include=\"Activation\\ActivationMetaDataConfigurationProviderSection.cs\" />\r\n    <Compile Include=\"Activation\\ActivationMetaDataProvider.cs\" />\r\n    <Compile Include=\"Activation\\IActivationMetaData.cs\" />\r\n    <Compile Include=\"Activation\\ActivationMetaData.cs\" />\r\n    <Compile Include=\"Activation\\IActivationMetaDataProvider.cs\" />\r\n <Compile Include=\"Collections\\DomainList.cs\" />\r\n    <Compile Include=\"DateTime\\GenerationDateRange.cs\" />\r\n    <Compile Include=\"DateTime\\DateBlitterExtensions.cs\" />\r\n    <Compile Include=\"Dto\\DTOStub.generic.cs\" />\r\n    <Compile Include=\"Dto\\Tabulation.cs\" />\r\n    <Compile Include=\"Dto\\TabulatedItem.cs\" />\r\n    <Compile Include=\"Dto\\DTOStub.cs\" />\r\n    <Compile Include=\"Environment\\EnvironmentContext.cs\" />\r\n    <C ompile Include=\"Events\\Delegates.cs\" />\r\n    <Compile Include=\"Activation\\ActivationHelper.cs\" />\r\n    <Compile Include=\"Helpers\\ObjectScrubber.cs\" />\r\n    <Compile Include=\"Helpers\\SmtpHelper.cs\" />\r\n    <Compile Include=\"Interfaces\\INameHolder.cs\" />\r\n    <Compile Include=\"Interfaces\\IFrame.cs\" />\r\n    <Compile Include=\"Events\\FrameEventArgs.cs\" />\r\n    <Compile Include=\"Events\\PayloadedEventArgs.cs\" />\r\n    <Compile Include=\"Helpers\\DateHelper.cs\" />\r\n    <Compile Include=\"Helpers\\EnumerableDataSources.cs\" />\r\n    <Compile Include=\"Helpers\\EnumHelper.cs\" />\r\n    <Compile Include=\"Helpers\\StringsHelper.cs\" />\r\n    <Compile Include=\"Interfaces\\IIndexable.cs\" />\r\n    <Compile Include=\"Interfaces\\INameable.cs\" />\r\n    <Compile Include=\"Collections\\NamedList.cs\" />\r\n    <Compile Include=\"Interfaces\\IText.cs\" />\r\n    <Compile Include=\"Events\\KeyChangedEventArgs.cs\" />\r\n    <Compile Include=\"DateTime\\DateRange.cs\" />\r\n    <Co mpile Include=\"DateTime\\EntityDateRange.cs\">\r\n      <SubType>Code</SubType>\r\n    </Compile>\r\n    <Compile Include=\"DateTime\\IMinimumBoundedDateRange.cs\" />\r\n    <Compile Include=\"DateTime\\IDateRange.cs\" />\r\n    <Compile Include=\"Enumerations.cs\" />\r\n    <Compile Include=\"DateTime\\IEntityDateRange.cs\" />\r\n    <Compile Include=\"Interfaces\\IUserNotifier.cs\" />\r\n    <Compile Include=\"Collections\\IXtendedEnumerable.cs\" />\r\n    <Compile Include=\"Membership.cs\" />\r\n    <Compile Include=\"DateTime\\MinimumBoundedDateRange.cs\" />\r\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\r\n    <Compile Include=\"Properties\\Resources.Designer.cs\">\r\n      <AutoGen>True</AutoGen>\r\n      <DesignTime>True</DesignTime>\r\n     <DependentUpon>Resources.resx</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"SeriesCube.cs\" />\r\n    <Compile Include=\"Collections\\XList.cs\" />\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <Folder Include=\"Compression\\\" />\r\n  </Item Group>\r\n  <ItemGroup>\r\n    <EmbeddedResource Include=\"Properties\\Resources.resx\">\r\n      <Generator>ResXFileCodeGenerator</Generator>\r\n      <LastGenOutput>Resources.Designer.cs</LastGenOutput>\r\n    </EmbeddedResource>\r\n  </ItemGroup>\r\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\r\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r\n       Other similar extension points exist, see Microsoft.Common.targets.\r\n  <Target Name=\"BeforeBuild\">\r\n  </Target>\r\n  <Target Name=\"AfterBuild\">\r\n  </Target>\r\n  -->\r\n</Project>" 

?doc.Root.Name; {{http://schemas.microsoft.com/developer/msbuild/2003}Project}
        hashCode: 541551665
        localName: "Project"
        LocalName: "Project"
        Namespace: {http://schemas.microsoft.com/developer/msbuild/2003}
        NamespaceName: "http://schemas.microsoft.com/developer/msbuild/2003"
        ns: {http://schemas.microsoft.com/developer/msbuild/2003} 


?doc.Root.Descendants(); {System.Xml.Linq.XContainer.GetDescendants}
        name: null
        self: false
        System.Collections.Generic.IEnumerator<System.Xml.Linq.XElement>.Current: null
        System.Collections.IEnumerator.Current: null ?doc.Root.Nodes(); {System.Xml.Linq.XContainer.Nodes}
        System.Collections.Generic.IEnumerator<System.Xml.Linq.XNode>.Current: null
        System.Collections.IEnumerator.Current: null ?doc.Root.Attributes();

最佳答案

您在这一行中遇到异常:

Console.WriteLine("{0} {1}", el.Name, el.Attribute("id").Value);

因为至少根的第一个子元素,在您的示例中它是 PropertyGroup 不包含 id 属性。

我可以建议你将这一行重写为

Console.WriteLine("{0} {1}", el.Name, (string)el.Attribute("id"));

在这种情况下,您的代码不会抛出任何异常。

关于c# - 如何使用XDocument读取csproj文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18951821/

相关文章:

c# - 两个 C# 扩展泛型方法之间的调用不明确,其中 T :class and other where T:struct

.net - 使用 .NET 创建 TrueType 字体文件的子集

c# - 将分部 View 转换为 HTML

c# - 指数延迟客户端 API 调用

javascript - 将 cliendid 从控件作为参数从 ASP 传递到 javascript 函数

java - 如何将简单 Java 类的字段名称映射为名称-值对序列

sql-server - SQL Server 2008 的自定义字段

c# - TextWriter 不写入所有文件

c# - 识别未本地化的文本

c# - WPF 破坏布局