简体   繁体   中英

Search and replace a line in a .xml file in Python

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 eg 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.

you can use this for example.

import re
with open ("file.xml", "r") as myfile:
    data = myfile.read()

data = re.sub(r"android:name=\"android\.permission\.[A-Z\_]+", "xxxx", data)
print data

This will replace all the android.permission.TEXT to xxx.

you only have to replace that string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM