2010-01-16 22 views
5

Ho un xml con vari spazi dei nomi che vorrei query utilizzando .SelectNodes (stringa xPath)XPath per XML con spazio dei nomi

Il problema che ho notato è che la query XPath ritorno niente finché ho tutti quei namespace in giro.

  1. C'è comunque da dire XmlDocument.SelectNodes di ignorare quegli spazi e solo io ottenere gli elementi corretti (gli elementi che query non sembra avere namespace prefix)?

  2. se c'è, qualcuno può fornirmi un esempio su come farlo? cosa dovrei definire prima/quando interrogo i nodi?

Grazie per l'aiuto.

Correzione: io ancora non riesco a capire quale sia il problema. ecco il mio xml:

<feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:gf="http://schemas.google.com/finance/2007" 
     xmlns:gd="http://schemas.google.com/g/2005" > 
    <id>http://finance.google.com/finance/feeds/[email protected]/portfolios</id> 
    <updated>2009-12-15T19:32:21.000Z</updated> 
    <category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/finance/2007#portfolio" /> 
    <title type="text" >Portfolio Feed</title> 
    <link rel="alternate" type="text/html" href="http://finance.google.com/finance/portfolio?action=view" /> 
    <link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://finance.google.com/finance/feeds/default/portfolios" /> 
    <link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml" href="http://finance.google.com/finance/feeds/default/portfolios" /> 
    <link rel="self" type="application/atom+xml" href="http://finance.google.com/finance/feeds/default/portfolios" /> 
    <openSearch:totalResults>24</openSearch:totalResults> 
    <openSearch:startIndex>1</openSearch:startIndex> 
    <openSearch:itemsPerPage>24</openSearch:itemsPerPage> 
    <entry> 
    <id>http://finance.google.com/finance/feeds/[email protected]/portfolios/2</id> 
    <updated>2009-12-14T16:26:53.000Z</updated> 
    <category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/finance/2007#portfolio" /> 
    <title type="text" >Main</title> 
    <link rel="self" type="application/atom+xml" href="http://finance.google.com/finance/feeds/default/portfolios/2" /> 
    <link rel="edit" type="application/atom+xml" href="http://finance.google.com/finance/feeds/default/portfolios/2" /> 
    <gd:feedLink href="http://finance.google.com/finance/feeds/[email protected]/portfolios/2/positions" /> 
    <gf:portfolioData currencyCode="USD" gainPercentage="0.0" return1w="0.0" return1y="0.0" return3m="0.0" return3y="0.0" return4w="0.0" return5y="0.0" returnOverall="0.0" returnYTD="0.0" /> 
    </entry> 
</feed> 

e qui è il mio codice:

XmlDocument xml = ExecuteRequest (url);

 var xmlnsManager = new System.Xml.XmlNamespaceManager(xml.NameTable); 
     xmlnsManager.AddNamespace("xmlns:openSearch", "http://a9.com/-/spec/opensearchrss/1.0/"); 
     xmlnsManager.AddNamespace("xmlns:gf", "http://schemas.google.com/finance/2007"); 
     xmlnsManager.AddNamespace("xmlns:gd", "http://schemas.google.com/g/2005"); 

     var nodes = xml.SelectNodes("//feed/entry", xmlnsManager); 

e il conteggio dei miei nodi è ancora 0! qualche idea?

risposta

-1

trovato il problema in un altro post qui: No Nodes Selected from Atom XML document using XPath?

Grazie a tutti.

+1

Le risposte di solo collegamento sono scarse risposte. Dovresti includere il contenuto sostanziale della risposta collegata. Tuttavia, in questo caso, una volta che lo fai, la tua risposta sarà simile [risposta di Darrel Miller sopra] (http://stackoverflow.com/a/2075794/2704659), che, a mio parere, dovrebbe essere la risposta accettata qui, non tuo. –

9

È necessario creare un gestore di spazi dei nomi, configurare tutti gli spazi dei nomi che si desidera utilizzare e il loro prefisso e quindi in XPath, è necessario utilizzare il prefisso.

var doc = new XmlDocument(); 
doc.Load("myfile.xml"); 

var xmlnsManager = new System.Xml.XmlNamespaceManager(doc.NameTable); 
xmlnsManager.AddNamespace("ns", "http://example.org/schema.xsd"); 

doc.SelectNodes("//ns:MyElement",xmlnsManager); 

Attenzione: non ho compilato questo codice.

+1

+1, compila bene –

2

Io non sono come familiarità con l'API .NET, ma si potrebbe essere in grado di inviare in un XPATH più generico che ignora gli spazi dei nomi da corrispondenti su qualsiasi elemento (es. *) e utilizzando il local-name nei filtri predicato.

ad es. utilizzando /*[local-name()='foo']/*[local-name()='bar']/*[local-name()='baz'] per trovare ns:foo/ns:bar/ns:baz senza dichiarare lo spazio dei nomi ns.

In questo modo non è necessario eseguire il binding a un determinato spazio dei nomi in fase di compilazione e può passare in istruzioni XPATH arbritrarie.

Ovviamente, utilizzando le istruzioni XPATH inconsapevoli dello spazio dei nomi è possibile ottenere risultati non intenzionali (se il contenuto dello spazio dei nomi è misto con elementi con lo stesso nome) e XPATH è veramente dettagliato.

In XPath 2.0 è possibile utilizzare i caratteri jolly per i namespace: /*:foo/*:bar/*:baz, ma si dovrebbe usare per ottenere SaxonXSLT/XPath 2.0 supporto in .NET.

+0

In realtà, Altova dispone di un processore XSLT 2.0 gratuito basato su COM ma accessibile da .Net. (Http://www.altova.com/altovaxml.html) e Intel ha recentemente rilasciato il processore XSLT 2.0 che gira su finestre a 64 bit. http://software.intel.com/en-us/articles/intel-soa-expressway-xslt-20-processor/ –

Problemi correlati