Как вставить новый элемент под другой с помощью xmlstarlet?

Я использую два добавления отступа пространства и редактора (kwrite), который вставляет пробелы вместо вкладок, когда я поразил клавишу Tab.

25
задан simpatico 11 May 2011 в 07:06
поделиться

3 ответа

Используйте -s (или --subnode) вместо -i. Что касается бонуса, вы не можете вставить элемент с атрибутом напрямую, но поскольку каждая операция редактирования выполняется последовательно, чтобы вставить элемент, а затем добавить атрибут:

> xml ed -s /config -t elem -n sub -v "" -i /config/sub -t attr -n class -v com.foo test.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<sub class="com.foo"></sub></config>
22
ответ дан 28 November 2019 в 18:19
поделиться

У меня была похожая проблема: у меня был файл конфигурации Tomcat (server.xml), и мне пришлось вставить тег <Resource> с предопределенными атрибутами в раздел <GlobalNamingResources>.

Вот как это выглядело раньше:

<GlobalNamingResources>
    <!-- Editable user database that can also be used
         by UserDatabaseRealm to authenticate users
    -->
    <Resource name="UserDatabase"
              auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>

Вот что я хотел достичь:

<GlobalNamingResources>
    <!-- Editable user database that can also be used
         by UserDatabaseRealm to authenticate users
    -->
    <Resource name="UserDatabase"
              auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
    <Resource name="jdbc/templateassets"
              auth="Container"
              type="javax.sql.DataSource"
              driverClassName="com.mysql.jdbc.Driver"
              url="jdbc:mysql://DBHOST:DBPORT/DBNAME?createDatabaseIfNotExist=false&amp;useUnicode=true&amp;characterEncoding=utf-8"
              username="DBUSER"
              password="DBPASS"
              maxActive="150"
              maxIdle="10"
              initialSize="10"
              validationQuery="SELECT 1"
              testOnBorrow="true" />
</GlobalNamingResources>

Вот как я это сделал (фрагмент из скрипта оболочки):

if [ -n "$(xmlstarlet sel -T -t -v "/Server/GlobalNamingResources/Resource[@name='jdbc/templateassets']/@name" server.xml)" ]; then
  echo "Resource jdbc/templateassets already defined in server.xml"
else
  echo "Adding resource jdbc/templateassets to <GlobalNamingResources> in server.xml"
  xmlstarlet ed -P -S -L -s /Server/GlobalNamingResources -t elem -n ResourceTMP -v "" \
    -i //ResourceTMP -t attr -n "name" -v "jdbc/templateassets" \
    -i //ResourceTMP -t attr -n "auth" -v "Container" \
    -i //ResourceTMP -t attr -n "type" -v "javax.sql.DataSource" \
    -i //ResourceTMP -t attr -n "driverClassName" -v "com.mysql.jdbc.Driver" \
    -i //ResourceTMP -t attr -n "url" -v "jdbc:mysql://DBHOST:DBPORT/DBNAME?createDatabaseIfNotExist=false&useUnicode=true&characterEncoding=utf-8" \
    -i //ResourceTMP -t attr -n "username" -v "DBUSER" \
    -i //ResourceTMP -t attr -n "password" -v "DBPASS" \
    -i //ResourceTMP -t attr -n "maxActive" -v "150" \
    -i //ResourceTMP -t attr -n "maxIdle" -v "10" \
    -i //ResourceTMP -t attr -n "initialSize" -v "10" \
    -i //ResourceTMP -t attr -n "validationQuery" -v "SELECT 1" \
    -i //ResourceTMP -t attr -n "testOnBorrow" -v "true" \
    -r //ResourceTMP -v Resource \
    server.xml
fi

Хитрость заключается в том, чтобы временно дать уникальное имя новому элементу, чтобы его можно было найти позже с помощью выражения XPATH. После добавления всех атрибутов имя снова изменяется на Resource (с -r).

Значение других параметров xmlstarlet:

-P (or --pf)        - preserve original formatting
-S (or --ps)        - preserve non-significant spaces
-L (or --inplace)   - edit file inplace
34
ответ дан 28 November 2019 в 18:19
поделиться

Я попробовал трюк из Cellux выше, он работал отлично! Спасибо!! Но форматирование не сохранилось, просто чтобы попробовать, я избавился от опций -P и -S, и проблемы с форматированием исчезли! Я использую CentOS. Может быть, это может кому-то помочь.

0
ответ дан 28 November 2019 в 18:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: