从特定子元素获取元素的属性值

时间:2018-08-14 15:07:13

标签: android xml xmlstarlet

我正在尝试在Mac上使用xmlstarlet从子元素中获取元素的属性值,这是一个示例

我有一个包含很多这样的元素的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:configChangesandroid: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"/>

将提供任何帮助! :)

1 个答案:

答案 0 :(得分:1)

我制作了一个Shell脚本来帮助我做到这一点:)

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的{​​{1}}到文件中。 <activity>用于将每个属性中的sed替换为android:,因为不能使用d。然后,使用:可以轻松找到属性xmllintandroid:configChanges的值。

输出:

android:screenOrientation

符合预期

编辑:

ABC XXX 更改为f="$(grep "<activity" /tmp/foo.txt | tail -$b)"后,awk命令在foo.txt文件中获得了f="$(awk '/activity/{k=$0}END{print k}' /tmp/foo.txt)"的最后一次出现,这是因为之前的activity命令起作用,占据文件的前head -n $b File.xml >/tmp/foo.txt