Hey guys, new to the forum, but am in need of some help.
I am quite new to Python, but want to be able to program a simple script that basically does three things:
-1. Finds a string of text in an .xml file (the length of the string, and the location of it can be provided, as it never changes)
-2. Copy that string
-3. Open up another files (an .itl [iTunes Library]) and replace a certain string, with the copied one.

This is in hope of being able to automate this task.

The first issue I am having is in opening and finding the string within the .xml file.

Can anyone possibly help me with this? Or should I maybe consider a different language?

Thank you :)
Liam.

Recommended Answers

All 11 Replies

Hi Liam

How about this:

#!/usr/bin/python

xmlfile = open("your.xml", 'r')
 
string_len = 5 # say your string is 5 characters long
 
for line in xmlfile:
    anchor = line.find('your string here')
    string = line[anchor + 1:anchor + string_len]
    print string

This would find the string you want and then print it out. Of course you might want to do something a bit smarter with it...

Sorry if this isn't the best code, I'm a bit new to Python myself.

Cheers, Ollie

Can you provide a sample xml and itl, it's a pretty easy task to achieve.

Cheers and Happy coding...

I've uploaded two files:
iTunes Library.xml
iTunes Music Library.xml

Now the file "iTunes Library.xml" is actually "iTunes Library.itl", but the forum would not let me upload a .itl, so make sure to re-name "iTunes Library.xml" to "iTunes Library.itl"


(iTunes Music Library IS an .xml, do NOT rename it)


The string I am looking for is in the "iTunes Music Library.xml" file. The string is in the beginning 15 or so lines of the file, and is located at:

<key>Library Persistent ID</key><string>THIS IS THE STRING</string>

The string is 16 characters long, and consists solely of capital letters and numbers.


This string is also present in the "iTunes Library.itl" file.


What I need to do is prompt the user with a question, asking if they are on the original computer, or the new computer. Should the user select the original computer, I want the program to:
Open the "iTunes Music Library.xml" file, and find the string from above.
If the user selects the new computer option, I want the program to:
Open the "iTunes Music Library.xml" file on the computer, search for the string, then use it to locate that string in the "iTunes Library.itl" file. It would then prompt the user to input a 16 character string. Once this is done, it would replace the string found in the "iTunes Music Library.xml" and the "iTunes Library.itl" files, with the one inputted by the user.
So for example:
Open "iTunes Music Library.xml"
Find the string after

<key>Library Persistent ID</key><string>

and before

</string>

Copy the string
Open the "iTunes Library.itl"
Find the copied string
Prompt the user for a new 16 character string
Replace the original string in both files, with the one inputted by the user.

I hope this is clear, and not to annoying for people

Thanks guys you are amazingly helpful :D
Liam.


P.S -- if you are trying to grasp what I want to do, visit the link I posted in my original post.

You can do the rest. ;)

import binascii


def xml_key_find(xml_file):
    f_x = open(xml_file)
    f_xml = f_x.readlines()
    f_x.close()    
    for item in f_xml:
        if item.find('<key>Library Persistent ID</key>') != -1:
            before_xml, tag_before, rest_xml = str(item).partition('<key>Library Persistent ID</key><string>')
            key_xml, tag_after, after_xml = rest_xml.partition('</string>')
            print "Key on 'iTunes Music Library.xml':", key_xml
    return key_xml

def xml_key_replace(xml_file, old_key, new_key):
    f_x = open(xml_file)
    f_xml = f_x.read()
    f_x.close()    
    f_xml = f_xml.replace(old_key, new_key)
    f_x = open(xml_file, 'w')
    f_x.write(f_xml)
    f_x.close()

def itl_key_compare(itl_file, old_key):
    f_i = open(itl_file, 'rb')
    f_itl_bin = f_i.read()
    f_i.close()
    f_itl_hex = str(binascii.hexlify(f_itl_bin)).upper()
    results = f_itl_hex.find(old_key)
    if results != -1:
        return True
    else:
        return False

def itl_key_replace(itl_file, old_key, new_key):
    f_i = open(itl_file, 'rb')
    f_itl_bin = f_i.read()
    f_i.close()
    f_itl_hex = str(binascii.hexlify(f_itl_bin)).upper()
    f_itl_hex = f_itl_hex.replace(old_key, new_key.upper())
    f_i = open(itl_file, 'wb')
    f_itl_bin = binascii.unhexlify(f_itl_hex)
    f_i.write(f_itl_bin)
    f_i.close()

file_xml = 'iTunes Music Library.xml'

xml_key = xml_key_find(file_xml)

print xml_key

user_key = 'E5F4BA35355AC51A'

xml_key_replace(file_xml, xml_key, user_key)

file_itl = 'iTunes Library.itl'

valid = itl_key_compare(file_itl, xml_key)

print valid

itl_key_replace(file_itl, xml_key, user_key)

Just tell if you need help, hope the coding is clear enought.

Cheers and Happy coding.

EDIT: the code it's Pyhton 2.x, but it's easilly adjustable.

:(
Okay I guess this really shows how much of a beginning to Python I am,

thankyou so much Beat_Slayer, but exactly how do I implement your code/


sorry
Liam.

The implementation is on the page of the snippet.

You copy the class to your script, then do:

fxml = 'iTunes Music Library.xml'       # path to xml file
fitl = 'iTunes Library.itl'             # path to itl file

itk = ITunesLibKeys(fxml, fitl)

if not itk.valid_key:                      # if keys don't match
    itk.xml_key_replace(itk.itl_key)       # replace xml key with the itl key

Any question, just fell free to ask.

Hi Beat Slayer

Thanks for posting this solution. As a beginner to Python I posted the earlier "solution" (read:attempt) for this problem and I found your (obviously more advanced) approach interesting - and I wondered why did you convert the xml file to binascii? Does this improve performance?

Just looking to learn :)

Thanks

I convert no xml.

The '.itl' file is binnary, I convert it to hex so it's more easy to search and read the '.itl' key.

When replacing the key on '.itl' file, I read it, convert to hex, replace the key, and output it converted as bin again to file.

I don't see a need for performance in such a small task.

Cheers and happy coding.

It seems perfect, but how can I use it for a text file with all the values?

Don't bump old threads...start a new thread with your problem.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.