What is the correct use of XmlNode.SelectSingleNode(string xpath) in C#?
I'm having trouble dealing with some XML file (which is at the end of this post).
I wrote the following code in order to get Job_Id
data related to a given Job_Name
pattern whose owner Job_Owner
is the user running the 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);
}
I would expect that node.SelectSingleNode("//Job_Name")
seeks for a tag named Job_Name
only under the xml code represented by node
.
That is not what it seems to be happening, as it always return the same node, doesn't matter at what step of the foreach
it is (i.e. the node
selected from the nodes
changes, but the node.SelectSingleNode("//Job_Name")
always r开发者_开发知识库eturn the same content).
What is wrong with this code?
Thanks in advance!
--
The XML File looks like this:
<Data>
<Job>
<Job_Id>58282.minerva</Job_Id>
<Job_Name>sb_net4_L20_sType1</Job_Name>
<Job_Owner>mgirardis@minerva</Job_Owner>
<!--more tags-->
</Job>
<Job>
<!--etc etc etc-->
</Job>
<!--etc etc etc-->
</Data>
It's because you're using the '//' syntax in XPath. That specific syntax selects the first node in the document named that. Try looking at https://www.w3schools.com/xml/xpath_syntax.asp for information on XPath syntax.
If you're looking for child nodes, try just using the node name (IE: 'Job_Owner' instead of '//Job_Owner')
Infernex87 is correct that Job_Owner
is simple and effective for this case. However, if it were not a direct child, you could do:
.//Job_Owner
Just like for directories, .
is the current node, so this finds descendants of the current node, rather than the root of the document.
Infernex87 has nailed the reason. Going by your XML, I guess going the LINQ route might be a good option for you. If you wish to start, Scott Gu's blog is a great resource.
we did a big DOM /xML /SQL Routine with maXbox script:
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;
精彩评论