Как объявить пространства имен XPath в xmlstarlet?

Я новичок в xmlstarlet, поэтому надеюсь, что этот ответ будет простым.

Я пишу сценарий для изменения файлов Inkscape SVG из командной строки. Я выбрал инструмент xmlstarlet.

После тестирования синтаксиса команд в тестовых файлах у меня возникли проблемы с настоящими файлами SVG. Я думаю, что использование пространств имен сбивает меня с толку.

Пример файла:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->    
<svg
   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="603"
   height="1000"
   viewBox="0 0 159.54375 264.58334"
   version="1.1"
   id="svg8"
   inkscape:version="0.92.1 r"
   sodipodi:docname="test.svg"
   inkscape:export-filename="/home/user/dev/inkscape/test/1.png"
   inkscape:export-xdpi="96"
   inkscape:export-ydpi="96">
  <defs
     id="defs2">
    <linearGradient
       inkscape:collect="always"
       id="linearGradient6204">
      <stop
         style="stop-color:#8f1a22;stop-opacity:1;"
         offset="0"
         id="stop6200" />
      <stop
         style="stop-color:#8f1a22;stop-opacity:0;"
         offset="1"
         id="stop6202" />
    </linearGradient>
  </defs>
</svg>

Я хочу изменить Gradient6204 на Gradient9999.

Я написал эту команду, которая не работает (просто возвращает исходный файл).

xmlstarlet ed -u "/svg/defs/linearGradient[@id='linearGradient6204']/@id" -v 'linearGradient9999' text.txt

Я также попробовал еще раз, добавив пространства имен с помощью -N, но безуспешно. Я обнаружил, что если я удалю строку:

xmlns="http://www.w3.org/2000/svg"

из файла работает команда, которую я написал выше.

Каков правильный синтаксис для обновления файла SVG, описанного выше?


person John W    schedule 25.05.2017    source источник


Ответы (1)


Явное объявление пространства имен

Добавление -N s=http://www.w3.org/2000/svg, а затем использование префикса пространства имен s: работает:

xmlstarlet ed  -N s=http://www.w3.org/2000/svg -u "/s:svg/s:defs/s:linearGradient[@id='linearGradient6204']/@id" -v 'linearGradient9999' text.txt

Неявное объявление пространства имен по умолчанию

Начиная с XMLStarlet v1.2.1, явного определения командной строки для пространства имен по умолчанию (например, в случае с файлом SVG OP) можно избежать с помощью автоматической привязки _ к пространству имен по умолчанию:

1.3. Более удобное решение

XML-документы могут также использовать различные префиксы пространств имен для любого элемента в документе. Чтобы упростить обработку пространств имен, XMLStarlet (версии 1.2.1+) будет использовать префиксы пространств имен, объявленные в корневом элементе входного документа. Пространство имен по умолчанию будет привязано к префиксам _ и DEFAULT (в версиях 1.5.0+).

Итак, приведенную выше командную строку можно переписать как:

xmlstarlet ed -u "/_:svg/_:defs/_:linearGradient[@id='linearGradient6204']/@id" -v 'linearGradient9999' text.txt
person kjhughes    schedule 25.05.2017
comment
ОМГ, ТЫ СПАСИБО СПАСИБО ‹3 - person Eric Aska; 31.08.2020