2

How can I create XML files like this?

<?xml version="1.0" encoding="utf-8"?>

<data>

     <li class= 'playlistItem' data-type='local' data-mp3='PATH' >
        <a class='playlistNonSelected' href='#'>NAME</a>
     </li>

     ...

</data>

I'd create this dynamically and for each item I have, I'd fill in the PATH and NAME variables with the values I need.

I'm trying to use lxml. This is what I've come up with so far, but I don't think it's correct:

from lxml import etree

for item in my_list:
    root = etree.Element('li', class = 'playlistItem', data-type = 'local', data-mp3 = PATH)
    child = etree.Element('a', class = 'playlistNonSelected', href ='#')
    child.text = NAME

Even if the above was correct, I'm lost at this point, because if I have 20 items in the list, how can I do this for each of them and then write it all to an XML file? I've tried looking at other answers but most of the replies are to generate XML like this:

<root>
  <child/>
  <child>some text</child>
</root>

And I can't figure out how to generate the kind I need. Sorry if I've made obvious mistakes. I appreciate any help. Thank you!

1 Answer 1

3

You are on the right track save for a few minor syntax and usage issues:

  1. class is a Python keyword, you can't use it as a function parameter name (which is essentially what class = 'playlistItem' is doing
  2. data-type is not a valid variable name in Python, it will be evaluated as data MINUS type, consider using something like dataType or data_type. There might be ways around this but, IMHO, that would make the code unnecessarily complicated without adding any value (please see Edit #1 on how to do this)

That being said, the following code snippet should give you something usable and you can move on from there. Please feel free to let me know if you need any additional help:

from lxml import etree

data_el = etree.Element('data')

# You can do this in a loop and keep adding new elements
# Note: A deepcopy will be required for subsequent items
li_el = etree.SubElement(data_el, "li", class_name = 'playlistItem', data_type = "local", data_mp3 = "PATH")
a_el = etree.SubElement(li_el, "a", class_name = 'playlistNotSelected', href='#')

print etree.tostring(data_el, encoding='utf-8', xml_declaration = True, pretty_print = True)

This will generate the following output (which you can write to a file):

<?xml version='1.0' encoding='utf-8'?>
<data>
  <li class_name="playlistItem" data_mp3="PATH" data_type="local">
    <a class_name="playlistNotSelected" href="#"/>
  </li>
</data>

Edit #0:

Alternatively, you can also write to a file by converting it to an ElementTree first, e.g.

# Replace sys.stdout with a file object pointing to your object file:
etree.ElementTree(data_el).write(sys.stdout, encoding='utf-8', xml_declaration = True, pretty_print = True)

Edit #1:

Since element attributes are dictionaries, you can use set to specify arbitrary attributes without any restrictions, e.g.

li_el.set('class', 'playlistItem')
li_el.set('data-type', 'local')
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, this is helpful! But unfortunately, the project I'm working with needs the XML to be in the format class, data-type, and data-mp3. I tried your method and it wouldn't recognize the XML. I don't think it's possible for me to change that part of the project at this time. Is there any way to create the XML in this format?
Please see the last edit...that should solve your problem at the expense of making the code a little more verbose.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.