【问题标题】:How to use XPath contains in C#如何在 C# 中使用 XPath 包含
【发布时间】:2021-04-05 14:49:35
【问题描述】:

我正在努力使用 XPATH 中的 contains(text,'some text')。

我看到了这个链接How to use XPath contains(),但由于某种原因对我不起作用

我需要删除项目引用,因此我只想使用“ProjectName”进行选择(不指定完整路径) 我从这个答案How do I use Powershell to add/remove references to a csproj? 中获取了一个脚本(请参阅 RemoveReference.ps1)

这是我的代码,也是一个小提琴https://dotnetfiddle.net/Cq5fa6

using System;
using System.Xml;
                    
public class Program
{
    public static void Main()
    {
            //Declare the XML Document here
            XmlDocument Doc = new XmlDocument();

            //Load you xml here
            //Doc.LoadXml(TransportResponse.Response)
            Doc.LoadXml(@"<?xml version=""1.0"" encoding=""utf-8""?>
<Project ToolsVersion=""15.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
  <ItemGroup>
    <ProjectReference Include=""..\ProjectReferencesToolkit.Core\ProjectReferencesToolkit.Core.csproj"">
      <Project>{6c167ddd-7ce8-4087-9f8c-6986145b97d1}</Project>
      <Name>ProjectReferencesToolkit.Core</Name>
    </ProjectReference>
  </ItemGroup>
  <Import Project=""$(MSBuildToolsPath)\Microsoft.CSharp.targets"" />
</Project>
");

//I need to use contains here to only search for ProjectReferencesToolkit.Core.csproj (not specifying full path)
var XPath = String.Format("//a:ProjectReference[@Include='{0}']","..\\ProjectReferencesToolkit.Core\\ProjectReferencesToolkit.Core.csproj");    
    var nsmgr = new XmlNamespaceManager(Doc.NameTable);
    nsmgr.AddNamespace("a","http://schemas.microsoft.com/developer/msbuild/2003");
    var node = Doc.SelectSingleNode(XPath, nsmgr);
        
Console.WriteLine(node.InnerXml);
        
    }
}

【问题讨论】:

  • 你知道,一般来说我会说这是一个坏主意......你如何将字符串转义为 xpath 字符串?假设文件名是My'Beautiful'Flower.csproj...
  • 我没有那种 csproj 文件名。
  • 如果你不在你的项目或文件夹中尝试一些有趣的名字,你作为程序员的生活一定很无聊:-) :-) 如果你不破坏资源管理器,你就是' t 甚至玩 :-)

标签: c# xml xpath


【解决方案1】:

我认为这是个坏主意。在 XPath 中转义字符串很痛苦。

我正在做一个ends-with 而不是contains,这应该更适合你想要的。明明ends-with是XPath 2.0,.NET只支持1.0,所以只好用substring

string fileName = "ProjectReferencesToolkit.Core.csproj";
var XPath = string.Format("//a:ProjectReference[substring(@Include, string-length(@Include) - {0} + 1) = '{1}']", fileName.Length, fileName);

还有一点转义:

// https://stackoverflow.com/a/38254661/613130
public static string EscapeXPathString(string value)
{
    if (!value.Contains("'"))
    {
        return '\'' + value + '\'';
    }
    else if (!value.Contains("\""))
    {
        return '"' + value + '"';
    }
    else
    {
        return "concat('" + value.Replace("'", "',\"'\",'") + "')";
    }
}

在xml中:

<ProjectReference Include=""..\ProjectReferencesToolkit.Core\ProjectReferencesToolkit&quot;'.Core.csproj"">

然后:

string fileName = @"ProjectReferencesToolkit""'.Core.csproj";
string fileNameEscaped = EscapeXPathString(fileName);
var XPath = string.Format("//a:ProjectReference[substring(@Include, string-length(@Include) - {0} + 1) = {1}]", fileName.Length, fileNameEscaped);

(现在我已经摆脱了 XPath 字符串,我感觉好多了?)

【讨论】:

  • 谢谢,我试试看告诉你
【解决方案2】:

最好使用 LINQ to XML API。它自 2007 年起在 .Net Framework 中可用。

c#

void Main()
{
    XDocument xsdoc = XDocument.Parse(@"<?xml version='1.0' encoding='utf-8'?>
        <Project ToolsVersion='15.0'
                 xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
            <ItemGroup>
                <ProjectReference Include='..\ProjectReferencesToolkit.Core\ProjectReferencesToolkit.Core.csproj'>
                    <Project>{6c167ddd-7ce8-4087-9f8c-6986145b97d1}</Project>
                    <Name>ProjectReferencesToolkit.Core</Name>
                </ProjectReference>
            </ItemGroup>
            <Import Project='$(MSBuildToolsPath)\Microsoft.CSharp.targets'/>
        </Project>");
        
        string SearchFor = @"ProjectReferencesToolkit.Core.csproj";
        
        XNamespace ns = xsdoc.Root.GetDefaultNamespace();
        XElement xelem = xsdoc.Descendants(ns + "ProjectReference")
            .FirstOrDefault(x => x.Attribute("Include").Value.EndsWith(SearchFor));
        
        Console.WriteLine(xelem);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-30
    • 1970-01-01
    • 2017-08-08
    • 2014-02-19
    • 2018-05-22
    • 2015-10-17
    相关资源
    最近更新 更多