2011-01-10 16 views
27

sto cercando di scrivere del codice per leggere in un file * csproj utilizzando C#La lettura di un file * Csproj in C#

Il codice che ho è la seguente

XmlDocument xmldoc = new XmlDocument(); 
    xmldoc.Load(fullPathName); 

    XmlNamespaceManager mgr = new XmlNamespaceManager(xmldoc.NameTable); 
    //mgr.AddNamespace("x", "http://schemas.microsoft.com/developer/msbuild/2003"); 

    foreach (XmlNode item in xmldoc.SelectNodes("//EmbeddedResource")) 
    { 
     string test = item.InnerText.ToString(); 
    } 

utilizzando il debugger I può vedere che 'fullPathName" ha il valore corretto e il xmldoc una volta caricato abbia i contenuti corretti.

il xmldoc non ha 'nodi' anche se, come se il contenuto non sono riconosciuti come XML.

Utilizzando un editor XML il file * .csproj convalida un documento XML.

Dove sto andando male?

risposta

16

Si stavano avvicinando con il tuo Inoltre XmlNamespaceManager, ma non stava utilizzando nel metodo SelectNodes:

XmlNamespaceManager mgr = new XmlNamespaceManager(xmldoc.NameTable); 
mgr.AddNamespace("x", "http://schemas.microsoft.com/developer/msbuild/2003"); 

foreach (XmlNode item in xmldoc.SelectNodes("//x:ProjectGuid", mgr)) 
{ 
    string test = item.InnerText.ToString(); 
} 

(sono passato alla ricerca di un elemento diverso come il mio progetto non ha avuto alcun risorse incorporate)

9

Per completezza qui la versione XDocument, questo semplifica la gestione dello spazio dei nomi:

 XDocument xmldoc = XDocument.Load(fullPathName); 
     XNamespace msbuild = "http://schemas.microsoft.com/developer/msbuild/2003"; 

     foreach (var resource in xmldoc.Descendants(msbuild + "EmbeddedResource")) 
     { 
      string includePath = resource.Attribute("Include").Value; 
     } 
48

perché non utilizzare l'API MSBuild?

Project project = new Project(); 
project.Load(fullPathName); 
var embeddedResources = 
    from grp in project.ItemGroups.Cast<BuildItemGroup>() 
    from item in grp.Cast<BuildItem>() 
    where item.Name == "EmbeddedResource" 
    select item; 

foreach(BuildItem item in embeddedResources) 
{ 
    Console.WriteLine(item.Include); // prints the name of the resource file 
} 

è necessario fare riferimento all'assemblea Microsoft.Build.Engine

+2

La classe Progetto di Microsoft.Build.Engine è ormai deprecato. Qualche idea su come fare l'equivalente con la classe Project da Microsoft.Build.Evaluation (assembly Microsoft.Build)? –

+0

@ValeryLetroye, non l'ho provato, ma penso qualcosa come 'project.Items.Where (i => i.ItemType ==" EmbeddedResource ")' dovrebbe funzionare. –

+0

Questo è esattamente quello che stavo cercando! Un ottimo modo per rispettare tutti i target di riferimento di msbuild e le loro sostituzioni! Questa dovrebbe essere la soluzione migliore dal punto di vista tecnico. – Chris