解析 XML,获取特定名称的深层元素。 (C#)

Posted

技术标签:

【中文标题】解析 XML,获取特定名称的深层元素。 (C#)【英文标题】:Parsing XML, getting deep elements of specific name. (c#) 【发布时间】:2022-01-04 21:45:17 【问题描述】:

我想问你关于 XML 解析的问题,我尝试了很多方法,但从来没有得到我“想要/期望”的结果。 我想获取特定名称的所有元素(“packageReference”)和他的属性/子项(元素)。之后,我将收集并解析结果以获取“include”属性的值和名称为“version”的元素/属性的值

xml 示例(我感兴趣的元素在底部):

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
        <IsWebBootstrapper>false</IsWebBootstrapper>
        <PublishUrl>publish\</PublishUrl>
        <Install>true</Install>
        <UpdateIntervalUnits>Days</UpdateIntervalUnits>
    </PropertyGroup>
    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
        <DebugSymbols>true</DebugSymbols>
        <DebugType>full</DebugType>
        <Optimize>false</Optimize>
    </PropertyGroup>
    <ItemGroup>
        <Compile Include="Launch.cs" />
        <Compile Include="Launch.designer.cs">
          <DependentUpon>Launch.cs</DependentUpon>
        </Compile>
        <Compile Include="Main.cs" />
        <None Include="Info.plist">
          <SubType>Designer</SubType>
        </None>
    </ItemGroup>
    <ItemGroup>
        <Reference Include="System" />
        <Reference Include="System.Core" />
    </ItemGroup>
    <ItemGroup>
        <ProjectReference Include="..\..\Model\Project.Model.csproj">
          <Project>0511395F-513C-4F56-BF87-718CA49BB13B</Project>
          <Name>Project.Model</Name>
        </ProjectReference>
    </ItemGroup>
    <ItemGroup>
        <PackageReference Include="AutoMapper">
          <Version>7.0.1</Version>
        </PackageReference>
        <PackageReference Include="GMImagePicker.Xamarin">
          <Version>2.5.0</Version>
        </PackageReference>
        <PackageReference Include="IdentityModel">
          <Version>4.1.0</Version>
        </PackageReference>
        <PackageReference Include="Microsoft.AppCenter">
          <Version>4.3.0</Version>
        </PackageReference>
        <PackageReference Include="Microsoft.AppCenter.Analytics">
          <Version>4.3.0</Version>
        </PackageReference>
        <PackageReference Include="Microsoft.AppCenter.Crashes">
          <Version>4.3.0</Version>
        </PackageReference>
        <PackageReference Include="Package.Test" Version="1.1.21" />
    </ItemGroup>
  <ItemGroup />
</Project>

结果应该是:

AutoMapper;7.0.1
GMImagePicker.Xamarin;2.5.0
...
...
Package.Test;1.1.21

我的代码:

var text = System.IO.File.ReadAllText(@"C:\MyGit\TestXML3.csproj");
            
var root = XElement.Parse(text);
var packageReferencesElements = root.Descendants("PackageReference");
var packageReferencesElementsAndSelf = root.DescendantsAndSelf("PackageReference");
var packageReferencesElementsOffElement = root.Elements().DescendantsAndSelf("PackageReference");

我尝试了很多方法,但您可以在代码中看到的方法很少。 如果有我感兴趣的东西,我不想“进入”每个有孩子的元素并在循环中检查。一定有更好的办法。还有一点是我不确定我正在寻找的元素是否在 2 层或更深。

更新:当我知道它们有多深时,此代码正在获取我的信息......但是当我不知道它应该有多深时?

var root = XElement.Parse(fileString);
var itemGroupsELements = root.Elements().Where(x => x.Name.LocalName == "ItemGroup");

var packageReferenceElements = itemGroupsELements.Elements().Where(x => x.Name.LocalName == "PackageReference");
foreach (var packageReference in packageReferenceElements)

    string packageName = packageReference.Attribute("Include").Value;
    string version = (packageReference.Attribute("Version") != null)
                    ? packageReference.Attribute("Version").Value
                    : packageReference.Value;

    _packageList.Add(new Package()App = app, PackageName = packageName, PackageVersion = version, Project = projectName);

知道我做错了什么吗? 谢谢!

【问题讨论】:

【参考方案1】:

PackageReference(与文件中的所有其他元素一样)位于 XML 命名空间“http://schemas.microsoft.com/developer/msbuild/2003”中。您必须在对Descendants 的调用中指定命名空间:

XNamespace build = "http://schemas.microsoft.com/developer/msbuild/2003";
var packageReferencesElements = root.Descendants(build + "PackageReference");

【讨论】:

以上是关于解析 XML,获取特定名称的深层元素。 (C#)的主要内容,如果未能解决你的问题,请参考以下文章

按名称仅获取 XML 直接子元素

如何通过 JAXB xml 解析获取特定元素?

从 Java DOM 中的 XML 获取元素名称

XML解析器(Unmarshal)使用JaxB从xml文件中获取元素

如何使用 LINQ 在 XML 中按名称获取元素

如何在解析后获取xml文件的元素并在iPhone程序中对其进行验证