This is how my XML looks like.
<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="xxxxxxxx" android:versionName="xxxxx" package="xxxxxx" xmlns:android="xxxxxxxxxxxxxx">
<application android:hardwareAccelerated="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true">
</application>
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
</manifest>
I need to add the below line after the <application
android:networkSecurityConfig="@xml/network_security_config" android:requestLegacyExternalStorage="true"
So, the output should look like
<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="xxxxxxxx" android:versionName="xxxxx" package="xxxxxx" xmlns:android="xxxxxxxxxxxxxx">
<application android:networkSecurityConfig="@xml/network_security_config" android:requestLegacyExternalStorage="true" android:hardwareAccelerated="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true">
</application>
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
</manifest>
I've tried sed command but still no luck. everybody suggests to use XMLSTART.
sed -i '/<application/a android:networkSecurityConfig="@xml/network_security_config" android:requestLegacyExternalStorage="true"' AndroidManifest.xml
CodePudding user response:
If xmlstarlet
is not available or not preferred, adding an attribute to an element can be done with xmllint
with a bit of work
# get uses-feature element
uf="$(xmllint --xpath '/manifest/uses-feature' tmp.xml)"
# get application attributes
attrs="$(xmllint --xpath '/manifest/application/@*' tmp.xml | tr '\n' ' ')"
# append desired attributes
attrs =' android:networkSecurityConfig="@xml/network_security_config" android:requestLegacyExternalStorage="true"'
# build manifest inner xml
inner="<application $attrs></application>$uf"
# restore manifest inner xml (with @CharlesDuffy kind suggestion)
printf '%s\n' setrootns 'cd /manifest' "set $inner" save bye | xmllint --shell tmp.xml
Note: output from xmllint --xpath '/manifest/application/@*' tmp.xml
contains new lines that must be removed before using it on set
command
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
For other cases where content contains several nodes
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="xxxxxxxxxxxxxx" android:hardwareAccelerated="true" android:versionCode="xxxxxxxx" android:versionName="xxxxx" package="xxxxxx">
<a>text1</a>
<application android:hardwareAccelerated="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true"/>
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
<b>
<c>text2</c>
</b>
</manifest>
the following XPath should be used to get everything but the element to be changed
xmllint --xpath '/manifest/*[not(name()="application")]' tmp.xml
Result
<a>text1</a>
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
<b>
<c>text2</c>
</b>
CodePudding user response:
This might look like:
xmlstarlet ed \
-i '/manifest/application' -t attr -n android:networkSecurityConfig -v '@xml/network_security_config' \
-i '/manifest/application' -t attr -n android:requestLegacyExternalStorage -v true \
<in.xml >out.xml