2013-05-10 24 views
11

Tôi có một số XML:Làm thế nào để truy vấn không gian tên mặc định với MSXML

<?xml version="1.0" ?> 
<Project ToolsVersion="4.0"> 
    <PropertyGroup Condition="'$(key)'=='1111'"> 
      <Key>Value</Key> 
    </PropertyGroup> 
</Project> 

Note: Đây không phải là XML thực tế tôi đang sử dụng, nó chỉ là đẹp hơn và ngắn hơn, và chứng tỏ vấn đề.

Sử dụng MSXML tôi có thể truy vấn cho các nút:

IXMLDOMNode node = doc.selectSingleNode("//PropertyGroup/@Condition"); 

Và nó hoạt động tốt:

Điều kiện = " '$ (key)' == '1111'"

Nhưng đó không thực sự là XML tôi có

Thực tế XML tôi có chứa khai báo không gian tên:

xmlns = "http://schemas.microsoft.com/developer/msbuild/2003"

làm cho thực tế tài liệu XML:

<?xml version="1.0" ?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <PropertyGroup Condition="'$(key)'=='1111'"> 
      <Key>Value</Key> 
    </PropertyGroup> 
</Project> 

Bây giờ câu hỏi của tôi:

IDOMNode node = doc.selectSingleNode("//PropertyGroup/@Condition"); 

không trả về nút phù hợp.

Làm cách nào để truy vấn không gian tên mặc định bằng MSXML?

Note:

  • tôi đã biết how to query the non-default namespace in xml; bạn sử dụng:

    doc.setProperty("SelectionNamespaces", 
         "xmlns="http://schemas.microsoft.com/developer/msbuild/2003"); 
    
  • tôi đã biết how to query the default namespace in .NET. Bạn sử dụng người quản lý không gian tên, cung cấp cho các không gian tên mặc định một tên, sau đó truy vấn sử dụng tên đó, sau đó bạn có thể truy vấn không gian tên không phải mặc định vì nó không còn được mặc định

  • i thể chỉ cần xóa các xmlns nội dung phản cảm từ chuỗi XML tôi nhận được, nhưng tôi thà "làm điều đó một cách đúng đắn"

làm thế nào để tôi truy vấn "mặc định" , hoặc "vô danh" namespace sử dụng MSXML?


Note: Trong thực tế XML i đang sử dụng SQL Server XML SHOWPLAN đầu ra:

<?xml version="1.0" encoding="UTF-16" standalone="yes"?> 
    <ShowPlanXML Version="1.1" Build="10.50.1600.1" 
        xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan"> 
     <BatchSequence> 
      <Batch> 
      ... 
      </Batch> 
     </BatchSequence> 
    </ShowPlanXML> 

Một lần nữa bạn sẽ nhìn thấy lời tuyên bố vi phạm không gian tên.Xóa nó hoạt động, nhưng đó là tẻ nhạt.

Bạn đã thử những gì khác?

tôi cũng đã cố gắng thiết lập các SelectionNamespace:

doc.setProperty('SelectionNamespaces', 
     'xmlns="http://schemas.microsoft.com/developer/msbuild/2003"'); 

như Microsoft hints at in a KB article.

Làm thế nào để tôi nhận được không gian tên mặc định?

Thực tế tôi không care về không gian tên. Truy vấn của tôi có ý nghĩa và tôi muốn nó hoạt động. Vì vậy, một cách tiếp cận khác cho câu hỏi có thể là:

Làm cách nào tôi có thể truy vấn không gian tên mặc định cho dù, hay không, không có vấn đề gì, tên không gian tên đó (hoặc không)?

Note: msxml là mẹ đẻ mã, và sử dụng nó từ một trình biên dịch Win32 bản địa (tức là không có .NET framework hoặc CLR)

+0

Tôi đã cập nhật thêm một lần nữa. Nó đánh tôi khi lái xe về nhà từ rạp chiếu phim. – granadaCoder

+0

@granadaCoder Bạn đang trả lời StackOverflow khi xem phim !? –

+0

Trên ổ đĩa nhà, tôi đã đưa ra một vài "chu kỳ" CPU của tôi cho điều này ..... đài phát thanh của tôi vừa mới chết trên tôi. – granadaCoder

Trả lời

14

Rõ ràng cung cấp cho các namespace tên khi bạn thêm nó vào SelectionNamespaces:

doc.setProperty("SelectionNamespaces", 
     "xmlns:peanut='http://schemas.microsoft.com/developer/msbuild/2003'"); 

và sau đó truy vấn sử dụng rằng namespace:

IDOMNode node = doc.selectSingleNode("//peanut:PropertyGroup/@Condition"); 

Bạn có thể cung cấp cho không gian tên đó bất kỳ tên viết tắt nào bạn muốn (peanut trong trường hợp này). Và sau đó sử dụng chữ viết tắt làm tiền tố (peanut:PropertyGroup trong trường hợp này).

Đề xuất trước đây

Tôi sẽ thử chuyển sang Xml.Linq.

Đây là mẫu (có không gian tên).

 try 
    { 

     XDocument xDoc1 = XDocument.Parse("<?xml version=\"1.0\" ?><Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\"><PropertyGroup Condition=\"'$(key)'=='1111'\"><Key>Value</Key></PropertyGroup></Project>"); 
     XNamespace ns1 = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003"); 

     var list1 = from list in xDoc1.Descendants(ns1 + "Project") 
        from item in list.Elements(ns1 + "PropertyGroup") 
        /* where item.Element(ns + "HintPath") != null */ 
        where item.Attribute("Condition") != null 
        select new 
        { 
         MyCondition = item.Attribute("Condition") == null ? "Not Here!" : item.Attribute("Condition").Value, 
         MyFake = item.Attribute("DoesNotExistTest") == null ? "Not Here Sucker!" : item.Attribute("DoesNotExistTest").Value 
        }; 


     foreach (var v in list1) 
     { 
      Console.WriteLine(v.ToString()); 
     } 


     XDocument xDoc2 = XDocument.Parse("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\"?> <ShowPlanXML Version=\"1.1\" Build=\"10.50.1600.1\"     xmlns=\"http://schemas.microsoft.com/sqlserver/2004/07/showplan\">  <BatchSequence>   <Batch>Something I Threw In Here</Batch>  </BatchSequence> </ShowPlanXML> "); 
     XNamespace ns2 = XNamespace.Get("http://schemas.microsoft.com/sqlserver/2004/07/showplan"); 

     var list2 = from list in xDoc2.Descendants(ns2 + "ShowPlanXML") 
        from item in list.Elements(ns2 + "BatchSequence") 
        /*        where item.Attribute("Condition") != null */ 
        where item.Element(ns2 + "Batch") != null 
        select new 
        { 
         BatchValue = (item.Element(ns2 + "Batch") == null) ? string.Empty : item.Element(ns2 + "Batch").Value 
        }; 


     foreach (var v in list2) 
     { 
      Console.WriteLine(v.ToString()); 
     } 



    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.Message); 
    } 
+0

Xin lỗi, 'IXMLDOMNode', không phải' IDOMNode'. Đó là từ thư viện đối tượng *** native *** msxml COM. Và đây là từ bản địa không (ví dụ: không phải .NET) –

+0

Ok. Kiểm tra cập nhật của tôi để biết gợi ý. Tôi đoán, nhưng con số đó tốt hơn là để lại phản hồi .Net. – granadaCoder

+0

tôi quên cung cấp cho bạn câu trả lời; đã hoạt động. Thật khủng khiếp khủng khiếp khi bạn phải đặt tên cho vùng tên mặc định trước khi có thể sử dụng nó. Nhưng ít nhất đó là một giải pháp khả thi! –

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