2014-10-06 72 views
0

使用下面的代碼,我可以在我的Xml中接收所有<job>元素。但是,當我嘗試搜索名爲<Name>且其文本等於"receiverjob"的子項的作業時,即使作業存在,SelectNodes()方法也會返回零。無法獲取包含特定文本的特定類型的子節點

XmlDocument dom = new XmlDocument(); 
dom.Load(textBoxFilePath.Text); 
XmlNamespaceManager nsManager = new XmlNamespaceManager(dom.NameTable); 
nsManager.AddNamespace("d", "http://quartznet.sourceforge.net/JobSchedulingData"); 
XmlNodeList jobElements = dom.DocumentElement.SelectNodes("descendant::d:job[name=receiverjob]", nsManager); 

的Xml

<?xml version="1.0" encoding="UTF-8"?> 
<!-- This file contains job definitions in schema version 2.0 format --> 
<job-scheduling-data version="2.0" xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <processing-directives> 
    <overwrite-existing-data>true</overwrite-existing-data> 
    </processing-directives> 
    <schedule> 
    <job> 
     <name>receiverjob</name> 
     <group>receivergroup</group> 
     <job-type>Quartz.Server.ArgumentReceiverJob, Quartz.Server</job-type> 
     <job-data-map> 
     <entry> 
      <key>receivedargument</key> 
      <value>hamburger</value> 
     </entry> 
     </job-data-map> 
    </job> 
    <trigger> 
     <simple> 
     <name>argumentreceiverJobTrigger</name> 
     <group>argumentreceiverGroup</group> 
     <description>Simple trigger to simply fire sample job</description> 
     <job-name>receiverjob</job-name> 
     <job-group>receivergroup</job-group> 
     <misfire-instruction>SmartPolicy</misfire-instruction> 
     <repeat-count>-1</repeat-count> 
     <repeat-interval>10000</repeat-interval> 
     </simple> 
    </trigger> 
    <job> 
     <name>batchjob</name> 
     <group>batchGroup</group> 
     <job-type>Quartz.Server.BatchJob, Quartz.Server</job-type> 
     <durable>true</durable> 
     <recover>false</recover> 
    </job> 
    <trigger> 
     <cron> 
     <name>Trigger2</name> 
     <group>DEFAULT</group> 
     <job-name>batchjob</job-name> 
     <job-group>batchGroup</job-group> 
     <cron-expression>0/15 * * * * ?</cron-expression> 
     </cron> 
    </trigger> 
    <job> 
     <name>jobnamexxx</name> 
    </job> 
    <job> 
     <name>jobnamexxx</name> 
    </job> 
    <job> 
     <name>jobnamexxx</name> 
    </job> 
    </schedule> 
</job-scheduling-data> 

回答

1

我不是一個XPath專家,但我懷疑你的查詢現在正在努力找工作,其中name元素等於receiverjob元素。我懷疑你想是這樣的:

"descendant::d:job[name/text()='receiverjob']" 

這也有可能是你需要限定name元素在正確的命名空間:

"descendant::d:job[d:name/text()='receiverjob']" 

我會強烈考慮使用LINQ to XML相反,然而,它會真的很簡單(國際海事組織):

XDocument doc = XDocument.Load(textBoxFilePath.Text); 
XNamespace ns = "http://quartznet.sourceforge.net/JobSchedulingData"; 
var jobs = doc.Descendants(ns + "job") 
       .Where(x => (string) x.Element(ns + "name") == "receiverjob"); 

我不確定的XPath語法,但我對LINQ to XML版本充滿信心 - 這本身就是IMO解決方案的好處。 (當然,對於沒有使用LINQ to XML的XPath專家,情況可能相反。)

+0

謝謝!你的XPath工作。我仍然不知道爲什麼我要在任何地方都提到這個前綴。我真的需要學習LINQ to XML,但上週我花了一些時間學習XPath,如果它通過編寫一行代碼來返回查詢結果,那麼我認爲它是值得的。但是你是對的,我應該在LINQ中更好地自己。 – Disasterkid 2014-10-06 08:30:59

+0

@Pedram:前綴用於指定您希望該名稱空間中的元素......它是由於XML中的名稱空間繼承而引起的。請注意,我提出的四條線完全取代了您提交的五條線......如果您想將查詢放在一條線上,也可以這樣做......我只是認爲這種方式更具可讀性:) – 2014-10-06 08:32:36

+0

很難不同意你的看法。 – Disasterkid 2014-10-06 08:35:26

1

您還需要在name元素上應用前綴,並且需要引用字符串文字:"descendant::d:job[d:name = 'receiverjob']"

+0

你的回答也是對的馬丁,但是恐怕喬恩斯基特在你面前回答,所以我必須選擇他。 – Disasterkid 2014-10-06 08:31:46