Попытка заменить элемент элемента XML с помощью XDT и локатора XPath
Привет я пытаюсь заменить <cron-expression>
использование VS2012 XDT с помощью следующего преобразования в файле описания задания quartz.net. Я протестировал локатор XPath с помощью онлайн-тестера, и он возвращает "то, что мне нужно". Любая помощь приветствуется.
<schedule>
<trigger>
<cron xdt:Locator="XPath(//job-scheduling-data/schedule/trigger/cron[name='crontriggername2'])" >
<cron-expression xdt:Transform="Replace">***some data***</cron-expression>
</cron>
</trigger>
</schedule>
для образца XML-файла (Quartz.net)
<job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"><processing-directives>
<overwrite-existing-data>true</overwrite-existing-data>
</processing-directives>
<schedule>
<trigger>
<cron>
<name>crontriggername1</name>
<group>crontriggergroup1</group>
<description>crontriggerdesc1</description>
<job-name>crontriggerjobname1</job-name>
<job-group>crontriggerjgroup1</job-group>
<misfire-instruction>crontriggermisfile1</misfire-instruction>
<cron-expression>0/5 * * * * ?</cron-expression>
</cron>
</trigger>
<trigger>
<cron>
<name>crontriggername2</name>
<group>crontriggergroup2</group>
<description>crontriggerdesc2</description>
<job-name>crontriggerjobname2</job-name>
<job-group>crontriggerjgroup2</job-group>
<misfire-instruction>crontriggermisfile2</misfire-instruction>
<cron-expression>0/13 * * * * ?</cron-expression>
</cron>
</trigger>
</schedule>
XPath // данные-задания-расписания / расписания / триггера /cron[name='crontriggername2']
возвращает мне правильную группу элементов ( http://www.freeformatter.com/xpath-tester.html 1)
<cron>
<name>crontriggername2</name>
<group>crontriggergroup2</group>
<description>crontriggerdesc2</description>
<job-name>crontriggerjobname2</job-name>
<job-group>crontriggerjgroup2</job-group>
<misfire-instruction>crontriggermisfile2</misfire-instruction>
<cron-expression>0/13 * * * * ?</cron-expression>
</cron>
Я основал выражение на решении другого вопроса XDT в Log4net ( преобразование конфигурации log4Net)
Кто-нибудь может указать мне на правильное решение, это сводит меня с ума. Заранее спасибо.
5 ответов
Альтернативное решение, которое не требует каких-либо изменений в исходном файле:
<job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<schedule>
<trigger>
<cron xdt:Locator="XPath(//*[local-name()='job-scheduling-data']
/*[local-name()='schedule']
/*[local-name()='trigger']
/*[local-name()='cron']
[*[local-name() = 'name'] = 'MyTriggerName'])">
or this syntax...
<cron xdt:Locator="XPath(//*[local-name()='job-scheduling-data' and namespace-uri()='http://quartznet.sourceforge.net/JobSchedulingData']
/*[local-name()='schedule' and namespace-uri()='http://quartznet.sourceforge.net/JobSchedulingData']
/*[local-name()='trigger' and namespace-uri()='http://quartznet.sourceforge.net/JobSchedulingData']
/*[local-name()='cron' and namespace-uri()='http://quartznet.sourceforge.net/JobSchedulingData']
[*[local-name() = 'name'] = 'MyTriggerName'])">
<cron-expression xdt:Transform="Replace">***some data***</cron-expression>
</cron>
</trigger>
</schedule>
см. также я пытаюсь получить Xpath для значения, но получаю ошибку для вложенного условия
Примените псевдоним пространства имен к кварцевому пространству имен в файле преобразования (его можно оставить по умолчанию в файле конфигурации исходных заданий) и используйте этот псевдоним на всех кварцевых узлах, в том числе внутри XPath. Дополнительно вы можете использовать Condition
скорее, чем XPath
и, таким образом, указывается только часть выражения XPath, относящаяся к выражению текущего узла.
<?xml version="1.0" encoding="utf-8" ?>
<q:job-scheduling-data xmlns:q="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<q:schedule>
<q:trigger>
<q:cron xdt:Locator="Condition(q:name='crontriggername2')" >
<q:cron-expression xdt:Transform="Replace">***some data***</q:cron-expression>
</q:cron>
</q:trigger>
</q:schedule>
</q:job-scheduling-data>
Решение / Обновление -> добавить пространство имен к документу XML и XPath. Все, что мне нужно было сделать, это изменить XML и XPATH следующим образом.
Сначала измените файл XML, добавив пространство имен (xmlns: ns0)
<job-scheduling-data xmlns:ns0="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
... затем отредактируйте файл, добавив его ко всем узлам.
и, наконец, преобразование нуждается в пространстве имен
<job-scheduling-data xmlns:ns0="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<schedule>
<trigger>
<cron xdt:Locator="XPath(//job-scheduling-data/schedule/trigger/cron[name='crontriggername2'])" >
<cron-expression xdt:Transform="Replace">***some data***</cron-expression>
</cron>
</trigger>
</schedule>
Для справки эта ссылка помогла мне понять
Это потому, что ваш XML имеет пространство имен по умолчанию (http://quartznet.sourceforge.net/JobSchedulingData
).
Я ничего не знаю о XDT, поэтому я не уверен в простом способе объявить пространство имен, но попробуйте поискать "xdt xpath default namespace".
В то же время, вот подробный вариант с использованием local-name()
это должно работать...
XPath(//*[local-name()='job-scheduling-data']/*[local-name()='schedule']/*[local-name()='trigger']/*[local-name()='cron' and *[local-name()='name']='crontriggername2'])
XML-преобразование должно иметь то же пространство имен по умолчанию (xmlns
атрибут) в качестве исходного XML. Также вам не нужен атрибут xdt:Locator.
Это должно выглядеть так:
<job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<schedule>
<trigger>
<cron>
<cron-expression xdt:Transform="Replace">***some data***</cron-expression>
</cron>
</trigger>
</schedule>
</job-scheduling-data>