2008-09-19 14 views
10

J'essaye un XPath très basique sur this xml (même que ci-dessous), et il ne trouve rien. J'essaie à la fois .NET et this website, et XPaths tels que //PropertyGroup, /PropertyGroup et //MSBuildCommunityTasksPath ne fonctionnent tout simplement pas pour moi (ils ont compilé mais ne donnent aucun résultat).Quel est le problème avec mon XPath/XML?

Source 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

Si vous pouviez fournir un exemple de code court de ce que vous avez essayé dans .net, il sera plus facile de suggérer ce qui pourrait mal se passer. – morechilli

Répondre

16

Vous pouvez ajouter des espaces de noms dans votre code et tout cela, mais vous pouvez effectivement joker l'espace de noms. Essayez l'idiome XPath suivant.

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

() fonctionne habituellement aussi bien, comme dans:

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

EDIT: sont grands espaces de noms et je ne veux pas dire qu'ils ne sont pas importants, mais les caractères génériques est très pratique lors de la compilation de code prototype, d'outils de bureau uniques, d'expérimentation avec XSLT, etc. Équilibrez votre besoin de commodité avec un risque acceptable pour la tâche à accomplir. Pour info, si nécessaire, vous pouvez également supprimer ou réaffecter des espaces de noms.

+0

Merci! Vous n'avez aucune idée de combien de temps j'ai chassé pour cette réponse. Brillant! – Gerard

+0

Cette réponse vient de résoudre un problème que j'avais, merci! –

+0

@Abel Morelos - heureux que cela a aidé; quand j'ai enfin découvert cela il y a plusieurs mois, ça a rendu le travail XML ** tellement plus facile. –

1

Votre problème est avec l'espace de noms (xmlns = "http://schemas.microsoft.com/developer/msbuild/2003"). Vous recevez zéro noeud car vous ne le qualifiez pas avec l'espace de noms. Si vous supprimez l'attribut xmlns, votre XPath "// PropertyGroup" fonctionnera. La façon dont vous interrogez avec namespace implique généralement d'aliaser un xmlns par défaut en un identifiant (puisque celui-ci n'est pas spécifié sur l'attribut), et de sélectionner comme "// myXMLNStoken: PropertyGroup".

2

Les balises du document se retrouvent dans l'espace de noms "default" créé par l'attribut xmlns sans préfixe. Malheureusement, XPath seul ne peut pas interroger les éléments dans l'espace de noms par défaut. Je ne suis pas sûr des détails sémantiques, mais vous devez explicitement attacher un préfixe à cet espace de noms en utilisant n'importe quel outil hébergeant XPath.

Il existe peut-être un moyen plus court de le faire dans .NET, mais la seule façon que j'ai vu est via un NameSpaceManager. Une fois que vous ajoutez explicitement un espace de noms, vous pouvez interroger à l'aide du gestionnaire d'espace de noms comme si toutes les balises dans l'élément espaces de noms ont ce préfixe (j'ai choisi « 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); 
     } 
    } 
}