I need to read and replace a line in a .xml file. I tried almost everything that I could imagine based on Search and replace a line in a file in Python, also How to search and replace text in a file using Python?.
Then as a second step I thought that it would be possible to remove the line and print the new line on top based on Deleting a specific line in a file (python), also Deleting a line from a file in Python.
Unfortunately nothing worked correctly for me. Either the script writes all lines as the same output or the format is not correct after writing.
Then I start reading closser questions such as How to remove elements from XML using Python but again it was not I was trying to get as a final output.
Update: By accident I deleted one line and the whole xml code was not able to be seen.
Sample of *.xml file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="gcm.play.android.samples.com.gcmquickstart"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="23" />
<!-- [START gcm_permission] -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Required permission for App measurement to run. -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- [END gcm_permission] -->
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="gcm.play.android.samples.com.gcmquickstart.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
I am trying to remove the line package="gcm.play.android.samples.com.gcmquickstart"
with another line e.g. package="another.line"
The code that I am using:
def str_replace(file_input, keyword, str_new):
for line in fileinput.input(file_input, inplace=True):
line = line.rstrip('\r\n')
print line.replace(keyword, str_new)
fileinput.close()
return
But it does not work correctly it just finds the string in the line and replaces just the string.
Sample of desired *.xml file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="sample.different.line"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="23" />
<!-- [START gcm_permission] -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Required permission for App measurement to run. -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- [END gcm_permission] -->
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="gcm.play.android.samples.com.gcmquickstart.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Update 2: Thanks to Nelson Guaman Leiva I have found a partial solution to my problem. I can manage to find and replace the string on the specific point of my file. My new problem is that I can not found a way to match after the pattern=*whatever text here*
, I can only find and replace the whole word, I can not match and replace after the equal sign.
Sample of code based on new solution:
def find_and_replace(file_input, str_old, str_new):
with open(file_input, 'r') as fr:
xml_data = fr.read()
xml_data = re.sub(r'{}=\"(.+?)\"'.format(str_old), str_new, xml_data)
fr.closed
return
Update 3: I forgot to include the writing part of the process in the file, the code is included under. I am not sure if this process is the fastest or more sufficient to read and write but it is one possible solution.
Sample of code:
def str_replace(self, file_input, str_old, str_new):
with open(file_input, "r") as fr:
xml_data = fr.read()
xml_data = re.sub(r"{}=\"(.+?)\"".format(str_old), str_new, xml_data)
fr.closed
with open(file_input, "w") as fw:
fw.write(xml_data)
fw.closed
self.replace_string = xml_data
return self.replace_string
If I found a solution to my problem on how to match and replace everything after the package=*whatever here*
because currently I replace the whole line, but at least it works as expected.
Thank you for your time and effort in advance.