2008-09-19 23 views
10

Ich versuche eine sehr einfache XPath auf this xml (das gleiche wie unten), und es findet nichts. Ich versuche sowohl .NET und this website, und XPaths wie //PropertyGroup, /PropertyGroup und //MSBuildCommunityTasksPath sind einfach nicht für mich arbeiten (sie kompiliert aber Null Ergebnisse zurückgeben).Was ist falsch an meinem XPath/XML?

Quelle 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

Wenn Sie ein kurzes Codebeispiel von dem bereitstellen könnten, was Sie in .net versucht haben, wird es einfacher, Vorschläge zu machen, was schief gehen könnte. – morechilli

Antwort

16

Sie Namespaces hinzufügen können Sie den Code in und alle das, aber Sie können den Namespace effektiv mit Platzhalterzeichen versehen. Versuchen Sie das folgende XPath-Idiom.

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

name() arbeitet in der Regel auch, wie in:

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

EDIT: Namensräume sind groß und ich behaupte nicht, dass sie nicht wichtig sind, aber sie Platzhalter in handlichen kommt Beim Zusammenbauen von Prototyp-Code, einmaligen Desktop-Tools, Experimentieren mit XSLT und so weiter. Balance zwischen dem Bedürfnis nach Bequemlichkeit und einem akzeptablen Risiko für die anstehende Aufgabe. Zu Ihrer Information, wenn nötig, können Sie Namespaces auch entfernen oder neu zuweisen.

+0

Danke! Sie haben keine Ahnung, wie lange ich für diese Antwort gejagt habe. Brillant! – Gerard

+0

Diese Antwort hat gerade ein Problem gelöst, das ich hatte, danke! –

+0

@Abel Morelos - froh, dass es geholfen hat; als ich das vor vielen monden endlich entdeckt habe, hat es XML ** viel einfacher ** gemacht. –

1

Ihr Problem ist, mit dem Namespace (xmlns = "http://schemas.microsoft.com/developer/msbuild/2003"). Sie erhalten keine Knoten, da Sie sie nicht mit dem Namespace qualifizieren. Wenn Sie das xmlns-Attribut entfernen, funktioniert Ihr "// PropertyGroup" -XPath. Bei der Abfrage mit Namespace wird normalerweise ein Standard-XMLNs in einen Bezeichner eingefügt (da im Attribut kein Wert angegeben wird) und wie "// myXMLNStoken: PropertyGroup" ausgewählt.

2

Die Tags im Dokument enden im Namespace "default", der mit dem Attribut xmlns ohne Präfix erstellt wurde. Leider kann XPath allein keine Elemente im Standardnamespace abfragen. Ich bin mir eigentlich nicht sicher über die semantischen Details, aber Sie müssen diesem Namespace explizit ein Präfix hinzufügen, indem Sie das XPath-Tool verwenden.

Es gibt möglicherweise eine kürzere Möglichkeit, dies in .NET zu tun, aber die einzige Möglichkeit, die ich gesehen habe, ist über einen NameSpaceManager. Nachdem Sie explizit einen Namensraum hinzugefügt haben, können Sie den Namespace-Manager-Abfrage verwenden, als ob alle Tags im Namensraum Element, das Präfix (I ‚msbuild‘ gewählt haben):

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); 
     } 
    } 
}