FAQ
Hi all,
I use minidom to parse xml data from a file.
I know how to get the data:
"""

""" Parse the xml file """
xmlDocument = minidom.parse(self.configFile)
""" Parse xml main section """
mainSection = xmlDocument.getElementsByTagName('Config')
""" Parse xml Global section """
configSection = mainSection[0]

""" Parse Ports section """
socketList = configSection.getElementsByTagName('Sockets')

"""

Now I want to change a string that a retrieved from the file and write
it back to where it was. So, I get something, change it and write it
back.

How do I put the new string in the place of the old? How do I overwrite
the first value with the new value?

Thanks,


Johan


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/tutor/attachments/20050822/aa0ef43d/attachment.htm

Search Discussions

  • Danny Yoo at Aug 22, 2005 at 5:57 pm

    """ Parse the xml file """
    xmlDocument = minidom.parse(self.configFile)
    [code cut]

    Now I want to change a string that a retrieved from the file and write
    it back to where it was. So, I get something, change it and write it
    back.

    How do I put the new string in the place of the old? How do I overwrite
    the first value with the new value?

    Hi Johan,

    The documentation in:

    http://www.python.org/doc/lib/module-xml.dom.minidom.html

    has a small example where they insert text into an element:

    ###### (From the documentation)
    from xml.dom.minidom import getDOMImplementation
    impl = getDOMImplementation()
    newdoc = impl.createDocument(None, "some_tag", None)
    top_element = newdoc.documentElement
    text = newdoc.createTextNode('Some textual content.')
    top_element.appendChild(text)
    ######

    Elements have methods like appendChild(), replaceChild() and
    removeChild(). So it should be fairly straightforward to replace the
    existing text node with a new one.


    That being said, the DOM model is a bit verbose and feels very low-level.
    Have you looked at the third-party "ElementTree" module yet?

    http://effbot.org/zone/element-index.htm

    It's a bit more convenient to work with; its model maps better to Python.


    Good luck!
  • Johan Geldenhuys at Aug 30, 2005 at 10:24 am
    Thanks for he help, so far.

    I am still having some questions on writing my new string back to the
    xml file after I found what I was looking for and changed it.

    Extracts:

    xmlDocument = minidom.parse(file_name) # open existing file for parsing
    main = xmlDocument.getElementsByTagName('Config')
    main.getElementsByTagName('Connection')
    configSection = mainSection[0]

    for node in configSection: #Here I get the NamedNodeMap info
    password = node.getAttribute("password")
    # Do stuff to the password and I have 'newPass'
    node.removeAttribute('password') # I take out my old attribute
    and it's value
    node.setAttribute('password', newPass)


    At this stage I have my new attribute and it's new value, but how do I
    write that to my file in the same place?
    I have to get a 'writer', how do I do this?
    Do I have to write all the data back or can I just replace the pieces I
    changed?

    Thanks,

    Johan


    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: http://mail.python.org/pipermail/tutor/attachments/20050830/6bd5d473/attachment.htm
    -------------- next part --------------
    An embedded message was scrubbed...
    From: Danny Yoo <dyoo at hkn.eecs.berkeley.edu>
    Subject: Re: [Tutor] Writing to XML file with minidom
    Date: Mon, 22 Aug 2005 10:57:36 -0700 (PDT)
    Size: 3127
    Url: http://mail.python.org/pipermail/tutor/attachments/20050830/6bd5d473/attachment.mht
  • Kent Johnson at Aug 30, 2005 at 11:40 am

    Johan Geldenhuys wrote:
    Thanks for he help, so far.

    I am still having some questions on writing my new string back to the
    xml file after I found what I was looking for and changed it.

    Extracts:

    xmlDocument = minidom.parse(file_name) # open existing file for parsing
    main = xmlDocument.getElementsByTagName('Config')
    main.getElementsByTagName('Connection')
    configSection = mainSection[0]

    for node in configSection: #Here I get the NamedNodeMap info
    password = node.getAttribute("password")
    # Do stuff to the password and I have 'newPass'
    node.removeAttribute('password') # I take out my old attribute
    and it's value
    node.setAttribute('password', newPass)


    At this stage I have my new attribute and it's new value, but how do I
    write that to my file in the same place?
    I have to get a 'writer', how do I do this?
    The minidom docs say that DOM objects have a writexml() method:
    writexml(writer[,indent=""[,addindent=""[,newl=""]]])
    Write XML to the writer object. The writer should have a write() method which matches that of the file object interface.

    This is saying that 'writer' should act like a file object. So it can just be a file object obtained by calling open(). In other words something like
    f = open(file_name, 'w')
    xmlDocument.writexml(f)
    f.close()

    should do it. If you have non-ascii characters in your XML you should use codecs.open() instead of plain open() and encode your XML as desired (probably utf-8).
    Do I have to write all the data back or can I just replace the pieces I
    changed?
    You have to write it all back.

    Kent
  • Johan Geldenhuys at Aug 30, 2005 at 11:47 am
    That means that I have to compile the whole file from scratch in Python,
    minidom.
    I am not that good, yet, but will try.
    will it be easier to search for the string that I look for in the file
    (readlines) and then just write the pieces back again?

    Johan
    On Tue, 2005-08-30 at 07:40 -0400, Kent Johnson wrote:

    Johan Geldenhuys wrote:
    Thanks for he help, so far.

    I am still having some questions on writing my new string back to the
    xml file after I found what I was looking for and changed it.

    Extracts:

    xmlDocument = minidom.parse(file_name) # open existing file for parsing
    main = xmlDocument.getElementsByTagName('Config')
    main.getElementsByTagName('Connection')
    configSection = mainSection[0]

    for node in configSection: #Here I get the NamedNodeMap info
    password = node.getAttribute("password")
    # Do stuff to the password and I have 'newPass'
    node.removeAttribute('password') # I take out my old attribute
    and it's value
    node.setAttribute('password', newPass)


    At this stage I have my new attribute and it's new value, but how do I
    write that to my file in the same place?
    I have to get a 'writer', how do I do this?
    The minidom docs say that DOM objects have a writexml() method:
    writexml(writer[,indent=""[,addindent=""[,newl=""]]])
    Write XML to the writer object. The writer should have a write() method which matches that of the file object interface.

    This is saying that 'writer' should act like a file object. So it can just be a file object obtained by calling open(). In other words something like
    f = open(file_name, 'w')
    xmlDocument.writexml(f)
    f.close()

    should do it. If you have non-ascii characters in your XML you should use codecs.open() instead of plain open() and encode your XML as desired (probably utf-8).
    Do I have to write all the data back or can I just replace the pieces I
    changed?
    You have to write it all back.

    Kent

    _______________________________________________
    Tutor maillist - Tutor at python.org
    http://mail.python.org/mailman/listinfo/tutor

    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: http://mail.python.org/pipermail/tutor/attachments/20050830/13bffdf4/attachment.html
  • Kent Johnson at Aug 30, 2005 at 1:47 pm

    Johan Geldenhuys wrote:
    That means that I have to compile the whole file from scratch in Python,
    minidom.
    I am not that good, yet, but will try.
    No, not if I understand what you are trying to do - the xmlDocument you have is all the data from the file, just write it back out using the code I posted before.
    will it be easier to search for the string that I look for in the file
    (readlines) and then just write the pieces back again?
    That depends a lot on the data. If you can reliably find what you want by looking at a line at a time, that is a simple approach. But you are almost there with the minidom. Really, just add my three lines of code to what you already have. (Maybe for prudence use a different file name.)

    Kent
    Johan
    On Tue, 2005-08-30 at 07:40 -0400, Kent Johnson wrote:

    Johan Geldenhuys wrote:
    Thanks for he help, so far.

    I am still having some questions on writing my new string back to the
    xml file after I found what I was looking for and changed it.

    Extracts:

    xmlDocument = minidom.parse(file_name) # open existing file for parsing
    main = xmlDocument.getElementsByTagName('Config')
    main.getElementsByTagName('Connection')
    configSection = mainSection[0]

    for node in configSection: #Here I get the NamedNodeMap info
    password = node.getAttribute("password")
    # Do stuff to the password and I have 'newPass'
    node.removeAttribute('password') # I take out my old attribute
    and it's value
    node.setAttribute('password', newPass)


    At this stage I have my new attribute and it's new value, but how do I
    write that to my file in the same place?
    I have to get a 'writer', how do I do this?
    The minidom docs say that DOM objects have a writexml() method:
    writexml(writer[,indent=""[,addindent=""[,newl=""]]])
    Write XML to the writer object. The writer should have a write() method which matches that of the file object interface.

    This is saying that 'writer' should act like a file object. So it can just be a file object obtained by calling open(). In other words something like
    f = open(file_name, 'w')
    xmlDocument.writexml(f)
    f.close()

    should do it. If you have non-ascii characters in your XML you should use codecs.open() instead of plain open() and encode your XML as desired (probably utf-8).
    Do I have to write all the data back or can I just replace the pieces I
    changed?
    You have to write it all back.

    Kent

    _______________________________________________
    Tutor maillist - Tutor at python.org <mailto:Tutor at python.org>
    http://mail.python.org/mailman/listinfo/tutor
  • Johan Geldenhuys at Aug 31, 2005 at 6:09 am
    Kent,
    Thanks for the tip. I can write the changed data back to my xml file.
    One snag that I found is that the des encryption that I used for the
    data that is written back, it is not parsed correctly when the file is
    read again with the new data in it. There is non-printable characters or
    non-ascii chars in that gives errors from expat when the contents is
    parsed.
    I had to use a different encryption algorithm. I am going to do some
    tests on it now.

    Johan
    On Tue, 2005-08-30 at 09:47 -0400, Kent Johnson wrote:

    Johan Geldenhuys wrote:
    That means that I have to compile the whole file from scratch in Python,
    minidom.
    I am not that good, yet, but will try.
    No, not if I understand what you are trying to do - the xmlDocument you have is all the data from the file, just write it back out using the code I posted before.
    will it be easier to search for the string that I look for in the file
    (readlines) and then just write the pieces back again?
    That depends a lot on the data. If you can reliably find what you want by looking at a line at a time, that is a simple approach. But you are almost there with the minidom. Really, just add my three lines of code to what you already have. (Maybe for prudence use a different file name.)

    Kent
    Johan
    On Tue, 2005-08-30 at 07:40 -0400, Kent Johnson wrote:

    Johan Geldenhuys wrote:
    Thanks for he help, so far.

    I am still having some questions on writing my new string back to the
    xml file after I found what I was looking for and changed it.

    Extracts:

    xmlDocument = minidom.parse(file_name) # open existing file for parsing
    main = xmlDocument.getElementsByTagName('Config')
    main.getElementsByTagName('Connection')
    configSection = mainSection[0]

    for node in configSection: #Here I get the NamedNodeMap info
    password = node.getAttribute("password")
    # Do stuff to the password and I have 'newPass'
    node.removeAttribute('password') # I take out my old attribute
    and it's value
    node.setAttribute('password', newPass)


    At this stage I have my new attribute and it's new value, but how do I
    write that to my file in the same place?
    I have to get a 'writer', how do I do this?
    The minidom docs say that DOM objects have a writexml() method:
    writexml(writer[,indent=""[,addindent=""[,newl=""]]])
    Write XML to the writer object. The writer should have a write() method which matches that of the file object interface.

    This is saying that 'writer' should act like a file object. So it can just be a file object obtained by calling open(). In other words something like
    f = open(file_name, 'w')
    xmlDocument.writexml(f)
    f.close()

    should do it. If you have non-ascii characters in your XML you should use codecs.open() instead of plain open() and encode your XML as desired (probably utf-8).
    Do I have to write all the data back or can I just replace the pieces I
    changed?
    You have to write it all back.

    Kent

    _______________________________________________
    Tutor maillist - Tutor at python.org <mailto:Tutor at python.org>
    http://mail.python.org/mailman/listinfo/tutor
    _______________________________________________
    Tutor maillist - Tutor at python.org
    http://mail.python.org/mailman/listinfo/tutor

    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: http://mail.python.org/pipermail/tutor/attachments/20050831/fcc3cacd/attachment.htm
  • Travis Spencer at Aug 31, 2005 at 2:47 pm

    On 8/30/05, Johan Geldenhuys wrote:
    One snag that I found is that the des encryption that I used for the data that is
    written back, it is not parsed correctly when the file is read again with the new
    data in it. There is non-printable characters or non-ascii chars in that gives errors
    from expat when the contents is parsed.
    I had to use a different encryption algorithm. I am going to do some tests on it
    now.
    Put the cyphertext in a CDATA section, so the parser knows to ignore
    its contents:

    <?xml version="1.0"?>
    <root>
    <cyphertext><![CDATA[
    ^KI^[?+?6?
    ]]>
    </cyphertext>
    </root>

    --

    Regards,

    Travis Spencer

    P.S. Please don't send HTML e-mails.
  • Danny Yoo at Aug 31, 2005 at 7:00 pm

    One snag that I found is that the des encryption that I used for the
    data that is written back, it is not parsed correctly when the file is
    read again with the new data in it. There is non-printable characters
    or non-ascii chars in that gives errors from expat when the contents
    is parsed. I had to use a different encryption algorithm. I am going
    to do some tests on it now.
    Put the cyphertext in a CDATA section, so the parser knows to ignore
    its contents:

    <?xml version="1.0"?>
    <root>
    <cyphertext><![CDATA[
    ^KI^[?+?6?
    ]]>
    </cyphertext>
    </root>

    Hi Travis,


    Putting pure binary bytes in an XML file has a flaw: the issue is that the
    binary bytes themselves might contain characters that could be interpreted
    as XML! Even if we wrap the content in CDATA, there's nothing that really
    stops the bytes from containing the characters "]]>" to prematurely close
    off the CDATA tag.

    To get around this, we can use a technique called "ascii-armor" to wrap
    protection around the troublesome binary text.

    http://en.wikipedia.org/wiki/ASCII_armor

    Python comes with a common ascii-armoring algorithm called "base64", and
    it's actually very easy to use it. Let's do a quick example.


    Let's say we have some binary unprintable bytes, like this:

    ######
    someBytes = open('/usr/bin/ls').read(8)
    someBytes
    '\x7fELF\x01\x01\x01\x00'
    ######

    (Hey, look, an Elf! *grin*)

    Anyway, this ELF will probably pass through email poorly, because the
    bytes surrounding it are pretty weird. But we can apply base64 encoding
    on those bytes:

    ######
    encodedBytes = someBytes.encode('base64')
    encodedBytes
    'f0VMRgEBAQA=\n'
    ######

    And now it's in a form that should pass cleanly through. Decoding it is
    also a fairly easy task:

    ######
    encodedBytes.decode('base64')
    '\x7fELF\x01\x01\x01\x00'
    ######

    And now we've got our ELF back.


    Hope this helps!
  • Travis Spencer at Aug 31, 2005 at 7:22 pm

    On 8/31/05, Danny Yoo wrote:
    Hi Travis,
    Hey Danny,
    Putting pure binary bytes in an XML file has a flaw: the issue is that the
    binary bytes themselves might contain characters that could be interpreted
    as XML! Even if we wrap the content in CDATA, there's nothing that really
    stops the bytes from containing the characters "]]>" to prematurely close
    off the CDATA tag.
    Oh, sure. I didn't think that through, and if I had, I wouldn't have
    know how to work around it.
    To get around this, we can use a technique called "ascii-armor" to wrap
    protection around the troublesome binary text.

    http://en.wikipedia.org/wiki/ASCII_armor
    Brilliant. I won't forget the term "ascii-armor" if I ever find
    myself in Johan's shoes and I've forgotten the details.
    (Hey, look, an Elf! *grin*) HA!
    Hope this helps!
    Tremendously. Thanks, Danny!

    --

    Regards,

    Travis Spencer

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouptutor @
categoriespython
postedAug 22, '05 at 9:51a
activeAug 31, '05 at 7:22p
posts10
users4
websitepython.org

People

Translate

site design / logo © 2022 Grokbase