web-dev-qa-db-de.com

Was ist die korrekte Verwendung von XmlNode.SelectSingleNode (Zeichenfolge xpath) in C #?

Ich habe Probleme mit XML-Dateien (die am Ende dieses Beitrags stehen).

Ich habe den folgenden Code geschrieben, um Job_Id-Daten zu erhalten, die sich auf ein bestimmtes Job_Name-Muster beziehen, dessen Besitzer Job_Owner der Benutzer ist, der das Probram ausführt:

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

Ich würde erwarten, dass node.SelectSingleNode("//Job_Name") nach einem Tag namens Job_Name nur unter dem durch node dargestellten XML-Code sucht.

Dies scheint nicht der Fall zu sein, da es immer denselben Knoten zurückgibt. Es spielt keine Rolle, in welchem ​​Schritt von foreach es sich befindet (d. H. Das node, das aus den nodes-Änderungen ausgewählt wurde, aber der node.SelectSingleNode("//Job_Name") gibt immer denselben Inhalt zurück).

Was stimmt nicht mit diesem Code?

Danke im Voraus!

-

Die XML-Datei sieht folgendermaßen aus:

<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>
16
Girardi

Dies liegt daran, dass Sie in XPath die '//' - Syntax verwenden. Diese bestimmte Syntax wählt den ersten Knoten im Dokument mit dem Namen "this" aus. Unter https://www.w3schools.com/xml/xpath_syntax.asp finden Sie Informationen zur XPath-Syntax.

Wenn Sie nach untergeordneten Knoten suchen, verwenden Sie einfach den Knotennamen (IE: 'Job_Owner' anstelle von '// Job_Owner').

21
Infernex87

Infernex87 ist richtig, dass Job_Owner für diesen Fall einfach und effektiv ist. Wenn es jedoch kein direktes Kind wäre, könnten Sie Folgendes tun:

.//Job_Owner

Genau wie bei Verzeichnissen ist . der aktuelle Knoten. Er findet also Nachkommen des aktuellen Knotens und nicht den Stamm des Dokuments.

16

Infernex87 hat den Grund gefunden. Wenn Sie sich an Ihr XML orientieren, könnte die LINQ-Route eine gute Option für Sie sein. Wenn Sie anfangen wollen, ist Scott Gus Blog eine großartige Ressource.

1
Arun

wir haben eine große DOM/xML/SQL-Routine mit dem maXbox-Skript erstellt:

 Funktion GetXMLFromURLAdr_IsSame_All (apath: string): boolean; 
 var 
 xml, Knoten: Olevariant; //IXMLDOMDocument;
 Node_row, node_se, nodex: olevariant; 
 I, j: Ganzzahl; 
 Sr1, sr2, basenod, basenod2, filePrefix, mySQL, odbcDSN, Auftrag: string ; 
 begin 
 xml: = CreateOleObject ('Microsoft.XMLDOM') as IXMLDocument; 
 xml.async: = False; 
 if xml.load (apath) dann writeln ('xml path load success2'); 
 wenn xml.parseError.errorCode <> 0, dann 
 writeln ('XML Load error:' + xml.parseError.reason); 
 basenod: = '/ WAB/Auftragsliste/Auftrag '; 
 Node_row: = xml.SelectNodes (basenod); 
 Writeln (' total auftrag node: '+ itoa (node_row.length)) 
 Try 
 für j: = 0 bis node_row.length-1 beginne 
 // node_se: = node_row.item [j] 
 node: = node_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
Max Kleiner