2014-10-06 4 views
0

Используя следующий код, я могу получить все элементы <job> в моем Xml. Тем не менее, когда я пытаюсь найти задания, у которых есть дочерний объект <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 к XML вместо этого, однако, где это было бы очень просто (IMO):

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. (Конечно, для эксперта XPath, который не использовал LINQ to XML, может быть и наоборот).

+0

Спасибо! Ваш XPath работал. Я все еще не знаю, почему я должен упомянуть этот префикс повсюду. Я честно должен изучить LINQ для XML, но я провел некоторое время на прошлой неделе, изучая XPath, и если он возвращает результаты запроса, я хочу, написав одну строку кода, тогда я думаю, что это того стоит. Но вы правы, я тоже должен быть в LINQ. – Disasterkid

+0

@Pedram: префикс должен указать, что вы хотите, чтобы элемент в этом пространстве имен ..., который он * является * из-за наследования пространства имен в XML. Обратите внимание, что четыре строки, которые я представил, полностью заменяют пять строк, которые вы представили ... и если вы хотите поместить запрос в одну строку, вы тоже можете это сделать ... Я просто думаю, что этот способ более читабельный :) –

+0

Трудно не согласиться с вами. – Disasterkid

1

Необходимо также применить префикс к элементу name, и вам нужно указать строковый литерал: "descendant::d:job[d:name = 'receiverjob']" ,

+0

Ваш ответ правильный, а также Мартин, но я боюсь, что Джон Скит ответил вам, поэтому я должен выбрать его. – Disasterkid

Смежные вопросы