C# 无法获取包含特定文本的特定类型的子节点

C# 无法获取包含特定文本的特定类型的子节点,c#,.net,xml,xpath,C#,.net,Xml,Xpath,使用下面的代码,我可以接收Xml中的所有元素。但是,当我尝试搜索具有名为的子项且其文本等于的“receiverjob”的作业时,SelectNodes()方法返回零,即使该作业存在 XmlDocument dom = new XmlDocument(); dom.Load(textBoxFilePath.Text); XmlNamespaceManager nsManager = new XmlNamespaceManager(dom.NameTable); nsManager.AddNames

使用下面的代码,我可以接收Xml中的所有
元素。但是,当我尝试搜索具有名为
的子项且其文本等于
的“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>

真的
接管人工作
接管人集团
Quartz.Server.ArgumentReceiverJob,Quartz.Server
接受者
汉堡包
接收者工作触发器
破产管理人小组
简单触发器,用于简单地触发示例作业
接管人工作
接管人集团
智能策略
-1
10000
批处理作业
批处理组
Quartz.Server.BatchJob,Quartz.Server
真的
假的
触发器2
违约
批处理作业
批处理组
0/15 * * * * ?
工作名称XXX
工作名称XXX
工作名称XXX

我不是XPath专家,但我怀疑您现在的查询正在尝试查找
name
元素等于
receiverjob
元素的作业。我怀疑你想要这样的东西:

"descendant::d:job[name/text()='receiverjob']"
您还可能需要限定
name
元素位于正确的命名空间中:

"descendant::d:job[d:name/text()='receiverjob']"
<>我将强烈地考虑使用LINQ到XML,然而,它将是非常简单的(IMO):


我不确定XPath语法,但我对LINQ-to-XML版本很有信心,这本身就是该解决方案优点的标志,IMO(当然,对于一位没有使用LINQ-to-XML的XPath专家来说,情况可能恰恰相反)

您还需要在
name
元素上应用前缀,并且需要引用字符串文字:
“后代::d:job[d:name='receiverjob']”“
谢谢!你的XPath成功了。我仍然不知道为什么我应该到处提到这个前缀。我确实需要学习linqtoxml,但上周我花了一些时间学习XPath,如果它通过编写一行代码返回我想要的查询结果,那么我认为这是值得的。但是你是对的,我也应该在LINQ方面做得更好。@Pedram:前缀是指定您希望该名称空间中的元素。。。这是由于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");