2010-09-19 29 views
10

Tôi chắc chắn thiếu một số chi tiết quan trọng tại đây. Tôi không thể làm cho XPath của .NET làm việc với các tệp dự án Visual Studio.XPath và * .csproj

Hãy tải một tài liệu xml:

var doc = new XmlDocument(); 
doc.Load("blah/blah.csproj"); 

Bây giờ thực hiện truy vấn của tôi:

var nodes = doc.SelectNodes("//ItemGroup"); 
Console.WriteLine(nodes.Count); // whoops, zero 

Tất nhiên, có những nút tên ItemGroup trong file. Hơn nữa, truy vấn này hoạt động:

var nodes = doc.SelectNodes("//*/@Include"); 
Console.WriteLine(nodes.Count); // found some 

Với các tài liệu khác, XPath hoạt động tốt. Tôi hoàn toàn bối rối về điều đó. Bất cứ ai có thể giải thích cho tôi những gì đang xảy ra?

+0

Làm thế nào về 'var nodes = doc.SelectNodes (" // */ItemGroup ");' Tôi đang ở Mac OS X nên không thể xác minh. – Strelok

Trả lời

14

Có thể bạn cần thêm tham chiếu vào không gian tên http://schemas.microsoft.com/developer/msbuild/2003.

Tôi gặp sự cố tương tự, tôi đã viết về nó here. Làm một cái gì đó như thế này:

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

không thể ** có thể ** làm việc, vì bạn chưa * sử dụng * bí danh ở bất kỳ đâu ... –

+0

Đây là sai ... –

+0

vâng, tôi đã bỏ lỡ bí danh trong xpath –

9

Nhìn vào không gian tên gốc; bạn sẽ phải bao gồm một trình quản lý không gian tên xml và sử dụng các truy vấn như "// x: ItemGroup", trong đó "x" là bí danh được chỉ định của bạn cho không gian tên gốc. Và chuyển người quản lý vào truy vấn. Ví dụ:

 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

Thêm một không gian tên đã làm các trick. Đáng tiếc là người ta không thể chấp nhận hai câu trả lời cho một câu hỏi :-) – catbert

+1

@catbert: bạn có thể đảo ngược câu trả lời hiện tại của bạn (sai) và chấp nhận câu trả lời đúng (@ Marc-Gravell). Không chỉ bạn có thể, nhưng bạn 'nên làm như vậy, bởi vì nếu không một số người sẽ nghĩ rằng câu trả lời sai/chấp nhận là chính xác. –

+0

+1 Điều này là khắt khe. –

5

tôi đăng tải một phiên bản LINQ/Xml qua tại:

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

Nhưng đây là ý chính của nó. Nó có thể không hoàn hảo 100% ...... nhưng nó cho thấy ý tưởng.

Tôi đăng mã ở đây, vì tôi đã tìm thấy mã này (bài đăng gốc) khi tìm kiếm câu trả lời. Sau đó, tôi đã mệt mỏi vì tìm kiếm và viết của riêng tôi.

  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

không hoàn hảo 100%? Nó phù hợp với tôi tốt nhưng những gì sẽ là cạm bẫy nếu bạn không nhớ tôi hỏi sau 2 năm – mechanicum

+0

Tôi không biết nó làm gì với GAC tài liệu tham khảo, đó là chỉ không biết, bởi vì tôi hiếm khi làm GAC tài liệu tham khảo bên ngoài khuôn khổ chính. Đó là về nó. Tôi vẫn sử dụng kịch bản khi tôi cần "báo cáo tham chiếu" của một người đàn ông nghèo ... – granadaCoder

Các vấn đề liên quan