2008-09-19 10 views
10

Próbuję bardzo podstawowy XPath na this xml (tak jak poniżej), i nie znajduje nic. Próbuję zarówno .NET i this website, a XPaths, takich jak //PropertyGroup, /PropertyGroup i //MSBuildCommunityTasksPath po prostu nie działają dla mnie (zostały skompilowane, ale zwracają zero wyników).Co jest nie tak z moim XPath/XML?

Źródło XML:

<?xml version="1.0" encoding="utf-8"?> 
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <!-- $Id: FxCop.proj 114 2006-03-14 06:32:46Z pwelter34 $ --> 
    <PropertyGroup> 
     <MSBuildCommunityTasksPath>$(MSBuildProjectDirectory)\MSBuild.Community.Tasks\bin\Debug</MSBuildCommunityTasksPath> 
    </PropertyGroup> 
    <Import 
     Project="$(MSBuildProjectDirectory)\MSBuild.Community.Tasks\MSBuild.Community.Tasks.Targets" /> 
    <Target Name="DoFxCop"> 
     <FxCop TargetAssemblies="$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.dll" 
      RuleLibraries="@(FxCopRuleAssemblies)" 
      AnalysisReportFileName="Test.html" 
      DependencyDirectories="$(MSBuildCommunityTasksPath)" 
      FailOnError="True" 
      ApplyOutXsl="True" 
      OutputXslFileName="C:\Program Files\Microsoft FxCop 1.32\Xml\FxCopReport.xsl" /> 
    </Target> 
</Project> 
+0

Jeśli możesz podać krótką próbkę kodu tego, czego próbujesz użyć w .net, łatwiej będzie Ci zasugerować, co może być nie tak. – morechilli

Odpowiedz

16

Możesz dodać przestrzenie nazw w kodzie i wszystko to, ale możesz efektywnie wprowadzić znak wieloznaczny w przestrzeń nazw. Wypróbuj następujący idiom XPath.

//*[local-name()='PropertyGroup'] 
//*[local-name()='MSBuildCommunityTasksPath'] 

nazwa() zazwyczaj działa tak samo, jak w:

//*[name()='PropertyGroup'] 
//*[name()='MSBuildCommunityTasksPath'] 

EDIT: Przestrzenie nazw są świetne a ja nie sugeruję, że nie są ważne, ale ich symboli wieloznacznych jest przydatna podczas łączenia kodu prototypowego, jednorazowych narzędzi pulpitu, eksperymentowania z XSLT i tak dalej. Zrównoważ swoją potrzebę wygody z akceptowalnym ryzykiem dla danego zadania. W razie potrzeby możesz również usunąć lub zmienić przypisanie przestrzeni nazw.

+0

Dziękuję! Nie masz pojęcia, jak długo polowałem na tę odpowiedź. Znakomity! – Gerard

+0

Ta odpowiedź właśnie rozwiązała problem, który miałem, dzięki! –

+0

@Abel Morelos - cieszę się, że pomógł; kiedy w końcu odkryłem te wiele księżyców temu, sprawiło, że XML działał **, więc ** znacznie łatwiej. –

1

Twój problem jest z przestrzeni nazw (xmlns = "http://schemas.microsoft.com/developer/msbuild/2003"). Otrzymujesz zero węzłów, ponieważ nie kwalifikujesz go w przestrzeni nazw. Jeśli usuniesz atrybut xmlns, będzie działać funkcja XPath "// PropertyGroup". Sposób wysyłania zapytań za pomocą przestrzeni nazw zazwyczaj wymaga aliasingu domyślnych xmlns do identyfikatora (ponieważ jeden nie jest określony w atrybucie) i wybrania w stylu "// myXMLNStoken: PropertyGroup".

2

Tagi w dokumencie kończą się na "domyślnej" przestrzeni nazw utworzonej przez atrybut xmlns bez prefiksu. Niestety, sama XPath nie może wyszukiwać elementów w domyślnej przestrzeni nazw. Właściwie nie jestem pewien szczegółów semantycznych, ale musisz wyraźnie dołączyć prefiks do tej przestrzeni nazw przy użyciu dowolnego narzędzia obsługującego XPath.

Może to być krótszy sposób to zrobić w .NET, ale jedynym sposobem, jaki widziałem jest za pośrednictwem NameSpaceManager. Po jawnie dodać nazw, można wyszukać za pomocą menedżera namespace jakby wszystkie tagi w przestrzeni nazw elementu mieć to prefix (wybrałem „msbuild”):

using System; 
using System.Xml; 

public class XPathNamespace { 
    public static void Main(string[] args) { 
     XmlDocument xmlDocument = new XmlDocument(); 
     xmlDocument.LoadXml(
    @"<?xml version=""1.0"" encoding=""utf-8""?> 
<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003""> 
    <!-- $Id: FxCop.proj 114 2006-03-14 06:32:46Z pwelter34 $ --> 

    <PropertyGroup> 
     <MSBuildCommunityTasksPath>$(MSBuildProjectDirectory)\MSBuild.Community.Tasks\bin\Debug</MSBuildCommunityTasksPath> 
    </PropertyGroup> 

    <Import Project=""$(MSBuildProjectDirectory)\MSBuild.Community.Tasks\MSBuild.Community.Tasks.Targets""/> 

    <Target Name=""DoFxCop""> 

     <FxCop 
      TargetAssemblies=""$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.dll"" 
      RuleLibraries=""@(FxCopRuleAssemblies)"" 
      AnalysisReportFileName=""Test.html"" 
      DependencyDirectories=""$(MSBuildCommunityTasksPath)"" 
      FailOnError=""True"" 
      ApplyOutXsl=""True"" 
      OutputXslFileName=""C:\Program Files\Microsoft FxCop 1.32\Xml\FxCopReport.xsl"" 
     /> 
    </Target> 

</Project>"); 

     XmlNamespaceManager namespaceManager = new 
    XmlNamespaceManager(xmlDocument.NameTable); 
     namespaceManager.AddNamespace("msbuild", "http://schemas.microsoft.com/developer/msbuild/2003"); 
     foreach (XmlNode n in xmlDocument.SelectNodes("//msbuild:MSBuildCommunityTasksPath", namespaceManager)) { 
      Console.WriteLine(n.InnerText); 
     } 
    } 
} 
Powiązane problemy