2014-10-06 88 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