Приятно видеть, что старая добрая Batch все еще может решить эту проблему. Очевидно, он не разработан с учетом поддержки XML, поэтому я бы порекомендовал инструмент, который изначально поддерживает его с помощью выражений XPath / XQuery, например xidel .
«Часть ECHO» легко:
xidel -s input.xml -e "concat('Your serial number is ',//LastSerialNumber,' where ',//LastSerialNumber + 1,' is the new number')"
Your serial number is 10 where 11 is the new number
Редактирование немного сложнее:
xidel -s input.xml --xquery "serialize(transform(/,function($x){$x/(if (name()='LastSerialNumber') then <LastSerialNumber>{node() + 1}</LastSerialNumber> else .)}),{'omit-xml-declaration':false()})"
<?xml version="1.0" encoding="UTF-8"?>
<BatchSettings>
<SerialFormat>{0:yyMMdd}{1:00}</SerialFormat>
<LastSerialDate>2020-05-27T00:00:00-05:00</LastSerialDate>
<LastSerialNumber>11</LastSerialNumber>
</BatchSettings>
- transform()
повторяется по каждому элементу-узлу. Он оставляет каждый из них нетронутым, кроме случая, когда он находит <LastSerialNumber>
. Затем он создает новый с исходным значением + 1. - serialize()
«преобразовывает» вывод, а с {'omit-xml-declaration':false()}
добавляет xml -объявление наверху.
serialize()
просто выводит вывод (в стандартный вывод). Чтобы записать вывод в файл, используйте вместо него file:write()
:
xidel -s input.xml --xquery "file:write('input.xml',transform(/,function($x){$x/(if (name()='LastSerialNumber') then <LastSerialNumber>{node() + 1}</LastSerialNumber> else .)}),{'omit-xml-declaration':false()})"
Чтобы объединить это с «частью ECHO»:
xidel -s input.xml --xquery "concat('Your serial number is ',//LastSerialNumber,' where ',//LastSerialNumber + 1,' is the new number'),file:write('input.xml',transform(/,function($x){$x/(if (name()='LastSerialNumber') then <LastSerialNumber>{node() + 1}</LastSerialNumber> else .)}),{'omit-xml-declaration':false()})"
Предварительно заданный запрос (с необходимыми escape-символами):
xidel -s input.xml --xquery ^"^
concat(^
'Your serial number is ',^
//LastSerialNumber,^
' where ',^
//LastSerialNumber + 1,^
' is the new number'^
),^
file:write(^
'input.xml',^
transform(^
/,^
function($x){^
$x/(^
if (name()='LastSerialNumber') then^
^<LastSerialNumber^>{node() + 1}^</LastSerialNumber^>^
else^
.^
)^
}^
),^
{'omit-xml-declaration':false()}^
)^
"
Это напечатает Your serial number is 10 where 11 is the new number
и отредактирует (и перезапишет) 'input. xml' .
[редактировать] {'omit-xml-declaration':false()}
работает только с Xidel 0.9.9 (начиная с xidel-0.9.9.20190104.6739.b64562007cb7
). В Xidel 0.9.8 вы можете вручную добавить xml -объявление:
xidel -s input.xml --xquery "concat('Your serial number is ',//LastSerialNumber,' where ',//LastSerialNumber + 1,' is the new number'),file:write('input.xml',('<?xml version=\"1.0\" encoding=\"UTF-8\"?>',transform(/,function($x){$x/(if (name()='LastSerialNumber') then <LastSerialNumber>{node() + 1}</LastSerialNumber> else .)})))"
[/ edit]