Эта проблема состоит из двух подзадач:
Нахождение максимума
xmlstarlet не имеет функции max()
, поэтому мы должны найти способ:
cat jumps.xml | \
xmlstarlet select -t -v "//pupil/jump[not(@height <= following-sibling::jump/@height) and not(@height < preceding-sibling::jump/@height)]/@height"
Обратите внимание на <=
и <
- если существует более одного максимального значения, будет взято только последнее.
Результат:
4
7
2
5
Обновление атрибут
Постоянное значение для практики
cat jumps.xml | xmlstarlet edit --update //pupil/@highestJump -v "Hahahaha"
... записывает Hahahaha
в каждый атрибут highestJump
.
Простой XPath
Взять осторожно: XPath, который вы используете для замены
- , относится к выбранному атрибуту (поэтому
.
равен сам атрибут ) - должен быть заключен в например.
string()
для получения эффекта
Итак:
cat jumps.xml | xmlstarlet edit --update //pupil/@highestJump -x "string(../@name)"
... дает (сокращено):
<pupil name="Adam" highestJump="Adam">
<pupil name="Berta" highestJump="Berta">
<pupil name="Caesar" highestJump="Caesar">
<pupil name="Doris" highestJump="Doris">
Объединение двух
cat jumps.xml | xmlstarlet edit --update //pupil/@highestJump -x "string(../jump[not(@height <= following-sibling::jump/@height) and not(@height < preceding-sibling::jump/@height)]/@height)"
... дает ...
<?xml version="1.0"?>
<sportsClass>
<pupils>
<pupil name="Adam" highestJump="4">
<jump height="4"/>
<jump height="1"/>
</pupil>
<pupil name="Berta" highestJump="7">
<jump height="4"/>
<jump height="7"/>
</pupil>
<pupil name="Caesar" highestJump="2">
<jump height="1"/>
<jump height="2"/>
</pupil>
<pupil name="Doris" highestJump="5">
<jump height="5"/>
<jump height="5"/>
</pupil>
</pupils>
</sportsClass>