2011-10-07 14 views
14

Ho problemi a gestire un file XML (che si trova alla fine di questo post).Qual è l'uso corretto di XmlNode.SelectSingleNode (stringa xpath) in C#?

ho scritto il seguente codice al fine di ottenere Job_Id dati relativi ad un determinato Job_Name modello il cui proprietario Job_Owner è l'utente che esegue il probram:

List<String> jobID = new List<String>(); 
XmlNodeList nodes = xml.SelectNodes("//Job"); 
foreach (XmlNode node in nodes) 
{ 
    innerNode = node.SelectSingleNode("//Job_Owner"); // SelectSingleNode here always selects the same node, but I thought it should be relative to node, not to nodes 
    if (!innerNode.InnerText.Contains(Environment.UserName)) 
    { 
     continue; 
    } 
    innerNode = node.SelectSingleNode("//Job_Name"); 
    if (!Regex.IsMatch(innerNode.InnerText, jobNamePattern, RegexOptions.Compiled)) 
    { 
     continue; 
    } 
    innerNode = node.SelectSingleNode("//Job_Id"); 
    jobID.Add(innerNode.InnerText); 
} 

Mi aspetterei che node.SelectSingleNode("//Job_Name") cerca di un tag di nome solo Job_Name sotto il codice xml rappresentato da node.

Questo non è quello che sembra accadere, come ritorno sempre lo stesso nodo, non importa in quale punto foreach è (cioè il node scelto fra i nodes modifiche, ma la node.SelectSingleNode("//Job_Name") ritornano sempre stesso contenuto).

Cosa c'è di sbagliato con questo codice?

Grazie in anticipo!

-

Il file XML si presenta così:

<Data> 
    <Job> 
     <Job_Id>58282.minerva</Job_Id> 
     <Job_Name>sb_net4_L20_sType1</Job_Name> 
     <Job_Owner>[email protected]</Job_Owner> 
     <!--more tags--> 
    </Job> 
    <Job> 
     <!--etc etc etc--> 
    </Job> 
    <!--etc etc etc--> 
</Data> 
+0

Questo programma è ora installato e funzionante! =) ~ Grazie per le risposte! – Girardi

risposta

19

E 'perché si sta utilizzando il '//' di sintassi nel XPath. Quella specifica sintassi seleziona il primo nodo nel documento chiamato così. Prova a guardare https://www.w3schools.com/xml/xpath_syntax.asp per informazioni sulla sintassi XPath.

Se siete alla ricerca di nodi figli, provare solo utilizzando il nome del nodo (IE: 'Job_Owner' invece di '// Job_Owner')

+2

Beh, questo funziona ... sapevo di quella sintassi ma sembrava ragionevole che se 'node' non contiene tutto il documento, allora quella sintassi non cercherebbe tutto il documento, ma cercherebbe solo all'interno del codice rappresentato da 'node' – Girardi

+0

Non è l'approccio migliore da usare // poiché fornirà valori errati nei casi in cui vi sono più Job_Owner su livelli diversi in quanto restituisce la prima occorrenza di qualsiasi Job_Owner. Il modo migliore è usare ./Job_Owner mentre cercherà rispetto al nodo corrente. – evhen14

+0

Quindi il punto è che se si avvia la query con/o //, in realtà non importa quale nodo si chiama 'SelectSingleNode()' on? –

1

Infernex87 ha inchiodato la ragione. Seguendo il tuo XML, immagino che percorrere la via LINQ potrebbe essere una buona opzione per te. Se si desidera iniziare, Scott Gu's blog è una grande risorsa.

+0

Sì, ho provato a cercare un po 'di LINQ in XML, ma non sono riuscito a trovare nulla di pragmatico là fuori (anche se non credo di averlo cercato abbastanza!). Grazie per il consiglio! – Girardi

14

Infernex87 è corretto che Job_Owner è semplice ed efficace per questo caso. Tuttavia, se non fosse un figlio diretto, si potrebbe fare:

.//Job_Owner 

Proprio come per le directory, . è il nodo corrente, in modo da questo trova discendenti del nodo corrente, piuttosto che la radice del documento.

0

abbiamo fatto un grande DOM routine/XML/SQL con lo script maXbox:

 
function GetXMLFromURLAdr_IsSame_All(apath: string): boolean; 
    var 
     xml, node: Olevariant; //IXMLDOMDocument; 
     nodes_row, nodes_se, nodex: olevariant; 
     i, j: Integer; 
     sr1,sr2, basenod, basenod2, filePrefix, mySQL, odbcDSN, Auftrag: string; 
    begin 
     xml:= CreateOleObject('Microsoft.XMLDOM') as IXMLDocument; 
     xml.async:= False; 
     if xml.load(apath) then writeln('xml path load success2'); 
     if xml.parseError.errorCode <> 0 then 
     writeln('XML Load error:' + xml.parseError.reason); 
     basenod:= '/WAB/Auftragsliste/Auftrag'; 
     nodes_row:= xml.SelectNodes(basenod); 
     writeln('total auftrag nodes: '+itoa(nodes_row.length)) 
     try 
     for j:= 0 to nodes_row.length-1 do begin 
      //nodes_se:= nodes_row.item[j] 
      node:= nodes_row.item[j]
// writeln(node.text) sr1:= node.selectSingleNode('.//Lieferanschrift/Ort').text sr1:= sr1 + node.selectSingleNode('.//Lieferanschrift/Strasse').text sr2:= node.selectSingleNode('.//Rechnungsanschrift/Ort').text; sr2:= sr2 + node.selectSingleNode('.//Rechnungsanschrift/Strasse').text; writeln(node.selectSingleNode('.//Auftragskopf/FremdlieferscheinNr').text); Auftrag:= node.selectSingleNode('.//Auftragskopf/FremdlieferscheinNr').text writeln(node.selectSingleNode('.//Auftragskopf/FremdlieferscheinNr').text);

if ANSICompareText(sr1, sr2) = 0 then begin srlist:= FindAllFiles(PDFFILEPATH,'*'+Auftrag+'_??.pdf',true); for it:= 0 to srlist.count-1 do begin writeln((srlist.strings[it])); if lCopyFile(srlist.strings[it], PDFEXPORT+extractfilename(srlist.strings[it]),true) then writeln('copyof=: '+srlist.strings[it]); end; srlist.free; srlist:= Nil; it:=0; result:= true; end else begin srlist:= FindAllFiles(PDFFILEPATH,'*'+Auftrag+'*.pdf',true); for it:= 0 to srlist.count-1 do begin if lCopyFile(srlist.strings[it], PDFEXPORT+extractfilename(srlist.strings[it]),true) then writeln('copyof<>: '+srlist.strings[it]); end; DeleteFiles(PDFEXPORT, '*RG.pdf'); DeleteFile(PDFEXPORT+'Special_'+Auftrag+'_ES.pdf'); srlist.free; result:= false end; //mk change in op fileprefix:= 'WAB'; odbcDSN:= 'advance_kmu_loc'; if filePrefix='WAB' then begin mySQL:= 'UPDATE verk_auftrag SET Status = 61 where Auftrag = '+Auftrag; writeln('order back: '+ itoa(MySQLQueryExecute2(mysql, odbcDsn, strtoint(Auftrag),true))); end; if filePrefix='WEA' then begin mySQL:= 'UPDATE verk_auftrag SET Status = 52 where Auftrag = '+Auftrag; writeln('order back: '+ itoa(MySQLQueryExecute2(mysql, odbcDsn, strtoint(Auftrag),true))); end; } nodes_se:= node.selectNodes('.//Auftragspositionen/Position'); writeln('total posnod: '+itoa(nodes_se.length)) for i:= 0 to nodes_se.length - 1 do begin node:= nodes_se.item[i]; writeln('Posit=' + node.text); end;//} writeln('------------------------'); end; //} except writeln(exceptiontoString(exceptiontype, exceptionparam)) finally xml:= unassigned; xml:= NULL; end; end;

+0

Ciao Max, puoi fornire alcuni suggerimenti utili su ciò che questo codice sta facendo che il codice dell'OP non lo fa? Perché è corretto e il loro codice non lo è? Qual è la differenza nel modo in cui funziona? Grazie in anticipo. –

+0

il codice analizza una data da un pacchetto di set di dati basato su XML (set di dati del client), copia alcuni file PDF e in base a tale aggiornamento un altro set di dati. Entrambi i codici sono corretti. –

Problemi correlati