Можно ли вставить вычисляемый атрибут (т.е. не константный) в файл XML с помощью xmlstarlet? - PullRequest
1 голос
/ 20 апреля 2020

У меня есть XML файл, подобный этому:

sources. xml

<?xml version="1.0" encoding="UTF-8"?>
<sources>
  <source>
    <identity id="abc"/>
    <somestuff/>
  </source>
  <source>
    <identity id="def"/>
    <someotherstuff/>
  </source>
</sources>

Я хочу избавиться от тега identity и передать его атрибут в родительский узел. Другими словами, мне нужно изменить мой входной файл на:

<?xml version="1.0" encoding="UTF-8"?>
<sources>
  <source id="abc">
    <somestuff/>
  </source>
  <source id="def">
    <someotherstuff/>
  </source>
</sources>

Я пытался:

xmlstarlet edit \
  --insert "//source" --type attr --name "id" --value "identity/@id" \
  --delete "//identity" \
  sources.xml

, который не работает, потому что --value понимает свой аргумент как постоянную строку.

Мой вопрос: возможно ли для xmlstarlet вычислить значение атрибута id в виде выражения XPATH, как в операциях select?

Edit nr. 1

Я нашел способ что-то сделать в этом направлении:

xmlstarlet edit \
  --insert "//source" --type attr --name "id" --value "{PLACE HOLDER}" \
  --update "//source/@id" --expr "../identity/@id" \
  --delete "//identity" \
  sources.xml

но я получаю пустые значения для атрибута id:

<?xml version="1.0" encoding="UTF-8"?>
<sources>
  <source id="">
    <somestuff>Hello</somestuff>
  </source>
  <source id="">
    <someotherstuff/>
  </source>
</sources>

Что не так в выражении ../identity/@id?

Ответы [ 2 ]

1 голос
/ 21 апреля 2020

Да, это возможно, и это решение:

xmlstarlet edit \
  --insert "//source" --type attr --name "id" \
  --update "//source/@id" --expr "string(../identity/@id)" \
  --delete "//identity" \
  sources.xml

Операция --insert не допускает --expr параметров, только --value, но --update делает. Таким образом, мы делаем это в два этапа: сначала создаем пустой атрибут, а затем меняем его значение с помощью --expr.

Нам также необходимо преобразовать текстовый узел, заданный в качестве аргумента, для опции --expr в строку с функцией XPATH string(). Это недостаточно документировано в ссылках или руководствах.

0 голосов
/ 23 апреля 2020

Я столкнулся с подобной проблемой, но та, где вычисляемый атрибут должен был быть взят из системной переменной. Итак, с разрешением OPs я решил опубликовать это здесь, для дальнейшего использования.

, если

myvar="hello"

, это вставит "привет" в качестве значения атрибута id :

xmlstarlet edit   --insert "//source" --type attr --name "id"\
   --update "//source/@id" --value "$myvar"   --delete "//identity"   sources.xml

Примечание: на этот раз мы должны использовать --value, а не --expr.

...