XPath and *.csproj

前端 未结 3 833
囚心锁ツ
囚心锁ツ 2020-12-06 05:50

I am for sure missing some important detail here. I just cannot make .NET\'s XPath work with Visual Studio project files.

Let\'s load an xml document:



        
相关标签:
3条回答
  • 2020-12-06 06:40

    You probably need to add a reference to the namespace http://schemas.microsoft.com/developer/msbuild/2003.

    I had a similar problem, I wrote about it here. Do something like this:

    XmlDocument xdDoc = new XmlDocument();
    xdDoc.Load("blah/blah.csproj");
    
    XmlNamespaceManager xnManager =
     new XmlNamespaceManager(xdDoc.NameTable);
    xnManager.AddNamespace("tu",
     "http://schemas.microsoft.com/developer/msbuild/2003");
    
    XmlNode xnRoot = xdDoc.DocumentElement;
    XmlNodeList xnlPages = xnRoot.SelectNodes("//tu:ItemGroup", xnManager);
    
    0 讨论(0)
  • 2020-12-06 06:42

    I posted a LINQ / Xml version over at:

    http://granadacoder.wordpress.com/2012/10/11/how-to-find-references-in-a-c-project-file-csproj-using-linq-xml/

    But here is the gist of it. It may not be 100% perfect......but it shows the idea.

    I'm posting the code here, since I found this (original post) when searching for an answer. Then I got tired of searching and wrote my own.

    using System;
    using System.Linq;
    using System.Xml.Linq;
    
                string fileName = @"C:\MyFolder\MyProjectFile.csproj";
    
                XDocument xDoc = XDocument.Load(fileName);
    
                XNamespace ns = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003");
    
                //References "By DLL (file)"
                var list1 = from list in xDoc.Descendants(ns + "ItemGroup")
                            from item in list.Elements(ns + "Reference")
                            /* where item.Element(ns + "HintPath") != null */
                        select new
                           {
                               CsProjFileName = fileName,
                               ReferenceInclude = item.Attribute("Include").Value,
                               RefType = (item.Element(ns + "HintPath") == null) ? "CompiledDLLInGac" : "CompiledDLL",
                               HintPath = (item.Element(ns + "HintPath") == null) ? string.Empty : item.Element(ns + "HintPath").Value
                           };
    
    
                foreach (var v in list1)
                {
                    Console.WriteLine(v.ToString());
                }
    
    
                //References "By Project"
                var list2 = from list in xDoc.Descendants(ns + "ItemGroup")
                            from item in list.Elements(ns + "ProjectReference")
                            where
                            item.Element(ns + "Project") != null
                            select new
                            {
                                CsProjFileName = fileName,
                                ReferenceInclude = item.Attribute("Include").Value,
                                RefType = "ProjectReference",
                                ProjectGuid = item.Element(ns + "Project").Value
                            };
    
    
                foreach (var v in list2)
                {
                    Console.WriteLine(v.ToString());
                }
    
    0 讨论(0)
  • 2020-12-06 06:45

    Look at the root namespace; you'll have to include an xml-namespace manager and use queries like "//x:ItemGroup", where "x" is your designated alias for the root namespace. And pass the manager into the query. For example:

            XmlDocument doc = new XmlDocument();
            doc.Load("my.csproj");
    
            XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
            mgr.AddNamespace("foo", doc.DocumentElement.NamespaceURI);
            XmlNode firstCompile = doc.SelectSingleNode("//foo:Compile", mgr);
    
    0 讨论(0)
提交回复
热议问题