2013-10-30 20 views
0

我想创建一个简单的工具来解析一个xml文件,如果/当某个元素被发现时,它会获取该值,然后使用该值执行代码,然后执行代码输出一个新值,然后替换它并保存一个新的XML文件。事实证明,这看起来很有价值,但这很困难。使用Linq到XML而不是XML读写器

现在我正在使用XML阅读器和XML编写器的组合。这是非常冗长的,我似乎有小问题,这是难以解决的方法。 You can see an example of my previous approach and it's code here.

我在想如果有人能帮我弄清楚如何使用Linq来做XML这个工作。我需要筛选原始文档的XML,查找“ClInclude”和“ClCompile”,当它们被发现时,我需要执行代码并用新值替换这些属性字符串。 For a better example of what I am accomplishing, you can check the post prior to the last.

我已经做了很多尝试,并决定把沟通的读者/作家好。任何人都可以帮我完成这件事?以下是我在做的LINQ到XML的尝试:

   string baseDir = (textBox2.Text + "\\" + safeFileName); 
       string vcName = Path.GetFileName(textBox1.Text); 
       string vcProj = Path.Combine(baseDir, vcName); 

       XDocument xmlDoc = XDocument.Load(textBox1.Text); 

       var items = from item in xmlDoc.Elements() 
          select item; 

       foreach (XElement itemElement in items) 
       { 
        if (itemElement.Name == "ClInclude") 
        { 
         // itemElement.SetElementValue("Include", "include/"); 
         textBox3.AppendText(itemElement.Value); 
        } 

       } 

       xmlDoc.Save(vcProj); 

现在,我只是他们附加到一个文本框,只是为了测试它。我似乎无法带回Clinclude或ClCompile中的任何元素。这里是我试图获得的价值,并更换线路的例子:

<ClCompile Include="..\..\lib\projx\conf.c" /> 
    <ClCompile Include="..\..\lib\projx\hash.c" /> 
    <ClCompile Include="..\..\lib\projx\init.c" /> 

这里是我解析XML的一个完整的例子:

<?xml version="1.0" encoding="utf-8"?> 
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <ItemGroup Label="ProjectConfigurations"> 
    <ProjectConfiguration Include="Debug|Win32"> 
     <Configuration>Debug</Configuration> 
     <Platform>Win32</Platform> 
    </ProjectConfiguration> 
    <ProjectConfiguration Include="Release|Win32"> 
     <Configuration>Release</Configuration> 
     <Platform>Win32</Platform> 
    </ProjectConfiguration> 
    </ItemGroup> 
    <PropertyGroup Label="Globals"> 
    <ProjectGuid>{57900E99-A405-49F4-83B2-0254117D041B}</ProjectGuid> 
    <Keyword>Win32Proj</Keyword> 
    <RootNamespace>libprojx</RootNamespace> 
    </PropertyGroup> 
    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> 
    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> 
    <ConfigurationType>DynamicLibrary</ConfigurationType> 
    <UseDebugLibraries>true</UseDebugLibraries> 
    <CharacterSet>MultiByte</CharacterSet> 
    <PlatformToolset>v110</PlatformToolset> 
    </PropertyGroup> 
    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> 
    <ConfigurationType>DynamicLibrary</ConfigurationType> 
    <UseDebugLibraries>false</UseDebugLibraries> 
    <WholeProgramOptimization>true</WholeProgramOptimization> 
    <CharacterSet>MultiByte</CharacterSet> 
    <PlatformToolset>v110</PlatformToolset> 
    </PropertyGroup> 
    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> 
    <ImportGroup Label="ExtensionSettings"> 
    </ImportGroup> 
    <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> 
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> 
    </ImportGroup> 
    <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> 
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> 
    </ImportGroup> 
    <PropertyGroup Label="UserMacros" /> 
    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> 
    <LinkIncremental>true</LinkIncremental> 
    </PropertyGroup> 
    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> 
    <LinkIncremental>false</LinkIncremental> 
    </PropertyGroup> 
    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> 
    <ClCompile> 
     <PrecompiledHeader> 
     </PrecompiledHeader> 
     <WarningLevel>Level3</WarningLevel> 
     <Optimization>MaxSpeed</Optimization> 
     <PreprocessorDefinitions>WIN32;projx_EXPORTS;_DEBUG;_WINDOWS;_USRDLL;LIBprojx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> 
     <AdditionalIncludeDirectories>..\..\Win32;..\..\lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> 
     <BasicRuntimeChecks>Default</BasicRuntimeChecks> 
     <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> 
    </ClCompile> 
    <Link> 
     <SubSystem>Windows</SubSystem> 
     <GenerateDebugInformation>true</GenerateDebugInformation> 
     <AdditionalLibraryDirectories>..\..\..\..\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> 
     <AdditionalDependencies>libdirect.lib;%(AdditionalDependencies)</AdditionalDependencies> 
    </Link> 
    </ItemDefinitionGroup> 
    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> 
    <ClCompile> 
     <WarningLevel>Level3</WarningLevel> 
     <PrecompiledHeader> 
     </PrecompiledHeader> 
     <Optimization>MaxSpeed</Optimization> 
     <FunctionLevelLinking>true</FunctionLevelLinking> 
     <IntrinsicFunctions>true</IntrinsicFunctions> 
     <PreprocessorDefinitions>WIN32;projx_EXPORTS;NDEBUG;_WINDOWS;_USRDLL;LIBprojx_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> 
     <AdditionalIncludeDirectories>..\..\Win32;..\..\lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> 
    </ClCompile> 
    <Link> 
     <SubSystem>Windows</SubSystem> 
     <GenerateDebugInformation>true</GenerateDebugInformation> 
     <EnableCOMDATFolding>true</EnableCOMDATFolding> 
     <OptimizeReferences>true</OptimizeReferences> 
     <AdditionalLibraryDirectories>..\..\..\..\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> 
     <AdditionalDependencies>libdirect.lib;%(AdditionalDependencies)</AdditionalDependencies> 
    </Link> 
    </ItemDefinitionGroup> 
    <ItemGroup> 
    <ClCompile Include="..\..\lib\projx\conf.c" /> 
    <ClCompile Include="..\..\lib\projx\hash.c" /> 
    <ClCompile Include="..\..\lib\projx\init.c" /> 
    <ClCompile Include="..\..\lib\projx\shmalloc.c" /> 
    <ClCompile Include="..\..\lib\projx\shm\fake.c" /> 
    <ClCompile Include="..\..\lib\projx\vector.c" /> 
    <ClCompile Include="dllmain.c" /> 
    </ItemGroup> 
    <ItemGroup> 
    <ClInclude Include="..\..\lib\projx\conf.h" /> 
    <ClInclude Include="..\..\lib\projx\hash.h" /> 
    <ClInclude Include="..\..\lib\projx\shmalloc.h" /> 
    <ClInclude Include="..\..\lib\projx\types.h" /> 
    <ClInclude Include="..\..\lib\projx\vector.h" /> 
    </ItemGroup> 
    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> 
    <ImportGroup Label="ExtensionTargets"> 
    </ImportGroup> 
</Project> 
+0

看看重载xmlDoc.Elements();你应该能够在那里指定一个名字并且只有那些元素的结果。另外,你的行与SQL语法?这可以只是'items = xmlDoc.Elements()'。你也可以看看.Descendants – Magus

回答

1

首先你要找到你ClInclude,据我所知:var includs = xdoc.Descendants("ClInclude")会给你所有的ClInclude。如果您需要特定ClInclude一些特殊包含属性值,你那样做:

var specificInclude = xdoc.Descendants("ClInclude") 
     .Where(inc => inc.Attribute("Include").Value == yourValue).FirstOrDefault(); 

接下来你需要替换包括与新的这样的属性值:

specificInclude.Attribute("Include").Value = newValue; 

控制台应用程序全部样本:

string xml = @"<root><ItemGroup><ClInclude id=""1""></ClInclude><ClInclude id=""2""></ClInclude></ItemGroup></root>"; 

var newxDoc = XDocument.Parse(xml); 

Console.WriteLine("Before"); 
Console.WriteLine(newxDoc.ToString()); 

var s = newxDoc.Descendants("ClInclude").Where(b => b.Attribute("id").Value == "2").FirstOrDefault(); 
s.Attribute("id").Value = "3"; 

Console.WriteLine("After"); 
Console.WriteLine(newxDoc.ToString()); 
Console.ReadLine(); 

希望有所帮助!

+0

很好的答案。我当时必须错过它。不知道它是如何发生的。非常抱歉。 – user1632018