Получение значения атрибута элемента из его конкретного подэлемента

Я пытаюсь использовать xmlstarlet на своем Mac, чтобы получить значение атрибута элемента из его подэлемента, вот пример

У меня есть файл xml с множеством подобных элементов, атрибуты вроде android:configChanges варьируются от элемента к элементу:

<activity android:configChanges="ABC" android:screenOrientation="XXX">
        <intent-filter>
            <action android:name="XYZ"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
</activity>

дело в том, что значение category android:name уникально для этого элемента, который равен android.intent.category.LAUNCHER.

Есть ли способ использовать xmllint или xmlstarlet, где я запускаю

xmlstarlet <magic code> <filename>

<magic code> должен быть в состоянии сказать значение android:configChanges и android:screenOrientation, когда предусмотрено, что /activity/intent-filter/category android:name = "android.intent.category.LAUNCHER"

таким образом, желаемый результат должен быть

android:configChanges="ABC" android screenOrientation="XXX"

пока единственное, что я знаю, это как получить значение других подэлементов из определенного подэлемента, используя

xmlstarlet sel -t -c "/activity/intent-filter/category[@android:name=android.intent.category.LAUNCHER]/*" file.xml

который возвращает

<action android:name="XYZ"/>
<category android:name="android.intent.category.LAUNCHER"/>

Любая помощь будет оценена! :)


person TheArmKing    schedule 14.08.2018    source источник


Ответы (1)


Я сделал сценарий оболочки, чтобы помочь мне сделать это :)

b="$(grep -n "android.intent.category.LAUNCHER" File.xml | cut -f1 -d:)"
head -n $b File.xml >/tmp/foo.txt
f="$(awk '/activity/{k=$0}END{print k}' /tmp/foo.txt)"
echo $f >> /tmp/file.xml
echo "</activity>" >> /tmp/file.xml
sed -i -e 's/android:/d/g' /tmp/file.xml
xmllint --xpath "string(//activity/@dconfigChanges)" /tmp/file.xml
xmllint --xpath "string(//activity/@dscreenOrientation)" /tmp/file.xml

Поскольку я использую операционную систему на основе Unix и не ограничиваюсь использованием только xmlstarlet, я сделал скрипт, который greps значение "android.intent.category.LAUNCHER", а затем использует head из этого файла, добавляя все строки выше "android.intent .category.LAUNCHER" в новый текстовый файл. чтобы найти первый экземпляр <activity, сценарий затем использует grep и tail для поиска в нижней части нового текстового файла. это возвращает полное значение <activity android:configChanges="ABC" android:screenOrientation="XXX"> в виде строки, используя echo и >>, строка выводится в виде файла xml. поскольку строка не содержит </activity>, скрипт echo <activity> в файл. sed используется для замены android: в каждом атрибуте на d, потому что : использовать нельзя. используя xmllint, мы можем легко найти значение атрибутов android:configChanges и android:screenOrientation.

Выход:

ABC
XXX

как и ожидалось

Изменить:

Изменено f="$(grep "<activity" /tmp/foo.txt | tail -$b)" на f="$(awk '/activity/{k=$0}END{print k}' /tmp/foo.txt)" команда awk получает последнее вхождение activity в файле foo.txt, она работает из-за предыдущей команды head -n $b File.xml >/tmp/foo.txt, которая принимает только первые b строки файла

person TheArmKing    schedule 17.08.2018