Powershell/C# XmlDocument 只选择没有属性的节点
Posted
技术标签:
【中文标题】Powershell/C# XmlDocument 只选择没有属性的节点【英文标题】:Powershell/C# XmlDocument selecting only the nodes without attributes 【发布时间】:2020-05-30 17:47:33 【问题描述】:我正在尝试读取 Visual Studio 项目文件以选择没有属性的 <PropertyGroup>
项以从 <AssemblyName>
节点中提取值。 post 接近我正在寻找的东西,但我需要它没有属性而不是没有特定属性
我在 Powershell 中尝试了以下操作,但没有成功。
$xml = [System.Xml.XmlDocument]::new();
$xml.Load("WebApplication4.csproj")
$ns = [System.Xml.XmlNamespaceManager]::new($xml.NameTable);
$ns.AddNamespace("prj", "http://schemas.microsoft.com/developer/msbuild/2003")
$xml.SelectNodes("//prj:PropertyGroup", $ns).Count
有没有办法在selectsinglenode
方法中使用xpath
语法,只返回一个没有属性的节点?
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.7\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.7\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
<Import Project="..\packages\Microsoft.Net.Compilers.2.1.0\build\Microsoft.Net.Compilers.props" Condition="Exists('..\packages\Microsoft.Net.Compilers.2.1.0\build\Microsoft.Net.Compilers.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>7EC4A73B-EA1B-4A6C-B2ED-093E3615C40E</ProjectGuid>
<ProjectTypeGuids>349c5851-65df-11da-9384-00065b846f21;fae04ec0-301f-11d3-bf4b-00c04f79efbc</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>WebApplication4</RootNamespace>
<AssemblyName>WebApplication4</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<UseIISExpress>true</UseIISExpress>
<Use64BitIISExpress />
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
</Project>
【问题讨论】:
【参考方案1】:仅使用 xpath 的另一种方法可能是:
$xml.SelectNodes("//prj:PropertyGroup[count(@*)=0]", $ns)
【讨论】:
【参考方案2】:Jack Fleeting's helpful answer 展示了如何仅使用 XPath 正确地完成它。
以下替代方法显示了如何在 PowerShell 代码中执行事后过滤。
您需要检查目标元素上.Attributes
集合的长度以找到没有属性的集合:
$xml.SelectNodes("//prj:PropertyGroup", $ns).Where( $_.Attributes.Count -eq 0 )
请注意,.Where()
是 PowerShell 提供的数组(集合)方法,可以通过脚本块 ( ...
) 过滤任何集合,该脚本块需要为每个元素 ($_
) 返回 $true
已选中。
【讨论】:
以上是关于Powershell/C# XmlDocument 只选择没有属性的节点的主要内容,如果未能解决你的问题,请参考以下文章
将 XDocument 转换为 XmlDocument,反之亦然
为啥`XmlDocument.LoadXml()`不适用于命名空间?