使用 Linq to XML 而不是 XML 读取器/编写器
本文关键字:XML 读取 Linq to 使用 | 更新日期: 2023-09-27 18:37:28
我正在尝试创建一个简单的工具来解析xml文件,如果/当找到某个元素时,它会获取该值,然后使用该值执行代码,然后执行的代码输出一个新值,然后将其替换并保存一个新的XML文件。事实证明,这比看起来值得的要困难得多。
现在我正在使用XML阅读器和XML编写器的组合。它非常冗长,我似乎遇到了一些小问题,很难解决。您可以在此处查看我之前的方法的示例及其代码。
我想知道是否有人可以帮助我弄清楚如何使用Linq to XML来完成这项工作。我需要筛选原始文档的XML以查找"ClInclude"和"ClCompile",当找到它们时,我需要执行代码并将这些属性字符串替换为新值。为了更好地说明我正在完成的工作,您可以在最后一个帖子之前查看帖子。
我做了很多尝试,并决定永远抛弃读者/作家。谁能帮我做到这一点?以下是我在 Linq to 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>
首先你需要找到你的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();
希望对您有所帮助!