1

I have a lot of xml files with a specific structure, for example

<Class>
    <Speed>25</Speed>
    <Price>3</Price>
</Class>

I want to replace the values from specific fields. I can do it manually but it will take a lot of time.

For example: I need to set Speed to 100 and Price to 50 in all files.

What I do now is I open each file, search for Speed and then manually type 50 there and so on. It takes a lot of time so I would like to know if there is a way to do it automatically via Notepad++ or other software.

Thanks in advance!

  • 1
  • Do you even need to use regular expressions given the fixed strings? I assume that it's <Speed>25</Speed> and this string is to be changed to <Speed>100</Speed>, then open Notepad++, Ctrl-Shift+F to open Find in Files. You can just choose the directory of the files. Find what is <Speed>25</Speed>, replace with is <Speed>100</Speed>, then click on "Replace in Files". You can then do the same for the other string. – HelpingHand Dec 26 '17 at 17:05
  • DavidPostill, there is too mch technical info and it is irrelevant to my question. HelpingHand, thing is the value is different all the time. In one file Speed is 25 in another it's 30 etc. so I can't do what you suggest. – Mike Dec 27 '17 at 17:58
  • Is it really <Speed>25</Name> or <Speed>25</Speed>? – Toto Dec 31 '17 at 11:33
1

Here's the recursive version of the script. It modifies the values in files in given directory and all its subdirectories.

import os
import re
my_dir = 'C:\\temp2\\my_folder\\'
replace_what = '(?<=<Speed>)(\d+)(?=<)'
replace_with = '100'
# loop through all files in directory recursively
for root, directories, filenames in os.walk(my_dir):
    for filename in filenames:
        if os.path.isfile(os.path.join(root,filename)):
            file = open(os.path.join(root,filename), 'r+')
            new_file_content=''
            for line in file:
                p = re.compile(replace_what)
                new_file_content += p.sub(replace_with, line)
            file.seek(0)
            file.truncate()
            file.write(new_file_content)
            file.close()
1

I assume there is a typo in your example and you have <Speed>25</Speed>

  • Ctrl+F
  • Find what: (?<=<Speed>)\d+(?=</Speed>)
  • Replace with: 100
  • check Wrap around
  • check Regular expression
  • Replace all

Explanation:

(?<=<Speed>)    : lookbehind, zero-length assertion to make sure we have "<Speed>" before current position
\d+             : 1 or more digits
(?=</Speed>)    : lookahead, zero-length assertion to make sure we have "</Speed>" after current position

Replacement:

100 : the new speed value

Do the same for the price, just replace Speed with Price in the above instructions.

0

You can try Python3.x for this purpose. I used Python as it’s available on many platforms. I tested this script on Windows and Ubuntu. I haven’t observed any issues. This snippet changes the Speed values only but feel free to modify the variable replace_what so that it changes whatever your need is.

import os
import re
my_dir = 'C:\\temp2\\my_folder\\'
replace_what = '(?<=<Speed>)(\d+)(?=<)'
replace_with = '100'
# loop through all files in directory
for fn in os.listdir(my_dir):
    #print(fn)
    pathfn = os.path.join(my_dir,fn)
    if os.path.isfile(pathfn):
        file = open(pathfn, 'r+')
        new_file_content=''
        for line in file:
            p = re.compile(replace_what)
            new_file_content += p.sub(replace_with, line)
        file.seek(0)
        file.truncate()
        file.write(new_file_content)
        file.close()
  • Thanks! I tested it and it's ok. Can you modify it so it searches in all sub-directories as well? I just realised I forgot to say my files are in subdirectories. So for example I have /my folder/car1 .../car2 /car3 and so on. – Mike Dec 30 '17 at 15:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.