2013-05-10 12 views
11

ho qualche XML:Come interrogare namespace di default con MSXML

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

Nota: Questo non è il vero e proprio XML sto usando, è solo più bella e più breve, e viene illustrato il problema.

Utilizzando MSXML posso interrogare per i nodi:

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

e funziona benissimo:

condizione = " '$ (chiave)' == '1111'"

Ma non è proprio l'XML che ho

In realtà l'XML che ho contiene una dichiarazione di namespace:

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

rendendo il reale documento 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> 

Ora la mia domanda:

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

non restituisce nodi corrispondenti.

Come faccio a interrogare lo spazio dei nomi predefinito utilizzando MSXML?

Nota:

  • so già how to query the non-default namespace in xml; si utilizza:

    doc.setProperty("SelectionNamespaces", 
         "xmlns="http://schemas.microsoft.com/developer/msbuild/2003"); 
    
  • so già how to query the default namespace in .NET. È possibile utilizzare il gestore di namespace, dare lo spazio dei nomi di default un nome, quindi query utilizzando quel nome, allora si può interrogare lo spazio dei nomi non predefinita dal momento che è non più di default

  • i può basta eliminare il xmlns testo offensivo dal stringa XML che ricevo, ma io preferirei "farlo nel modo giusto"

Come faccio a interrogare il "default", o "senza nome" namespace utilizzando MSXML?


Nota: In realtà l'XML sto usando XML ShowPlan di SQL Server uscita:

<?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> 

Anche in questo caso si può vedere la dichiarazione incriminata dello spazio dei nomi.La sua eliminazione funziona, ma è noioso.

Cos'altro hai provato?

Ho anche provato modificando il SelectionNamespace:

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

come Microsoft hints at in a KB article.

Come faccio a ottenere lo spazio dei nomi predefinito?

In realtà non lo sono assistenza su namespace. La mia domanda ha un senso e voglio che funzioni. Quindi, Un altro approccio alla domanda potrebbe essere:

Come posso interrogare lo spazio dei nomi predefinito, indipendentemente dal fatto che il nome dello spazio dei nomi sia (o non sia)?

Nota: msxml è codice nativo, ed il suo utilizzo da un compilatore nativo Win32 (cioè nessun framework .NET o CLR)

+0

Ho effettuato un altro aggiornamento. Mi ha colpito mentre guidavo verso casa dal cinema. – granadaCoder

+0

@granadaCoder Stavi rispondendo StackOverflow mentre guardavi un film !? –

+0

Sul disco di casa, ho dato alcuni dei miei "cicli" della CPU a questa cosa ... la mia radio è appena morta su di me. – granadaCoder

risposta

14

esplicitamente dare lo spazio dei nomi un nome quando si aggiunge al SelectionNamespaces:

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

e quindi interrogare utilizzando quel namespace:

01.235.164,106174 millions

È possibile assegnare a tale spazio dei nomi qualsiasi nome di abbreviazione desiderato (peanut in questo caso). E quindi utilizzare l'abbreviazione come prefisso (peanut:PropertyGroup in questo caso).

suggerimenti precedenti

vorrei provare a spostare a Xml.Linq.

Ecco un esempio (con uno spazio dei nomi).

 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

Siamo spiacenti, 'IXMLDOMNode', non' IDOMNode'. È dalla libreria di oggetti COM nativi *** msxml. E questo è nativo non (cioè non .NET) –

+0

Ok. Controlla il mio aggiornamento per un suggerimento. Sto indovinando, ma la figura è meglio che lasciare la giusta risposta .Net. – granadaCoder

+0

ho dimenticato di darti la risposta; quello ha funzionato. È orribilmente terribile che devi nominare lo spazio dei nomi predefinito prima che tu possa usarlo. Ma almeno è una soluzione praticabile! –

Problemi correlati