Using elementtree: replacing nodes

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • André

    #1

    Using elementtree: replacing nodes

    I've started using elementtree and don't understand how to use it to
    manipulate and replace nodes. I know how to do this using a simple,
    but inefficient parser I wrote, but I'd rather learn to use a better
    tool - especially as it is to be added to the standard library.

    I'll use a simple, but representative example. Suppose I have the
    following text, where I inserted blank lines to isolate the part I want
    to manipulate.
    =============== ====
    <html>
    <body>
    <p>
    This is some text.
    </p>

    <pre class="text">
    a = 6*7
    print a
    </pre>

    <p>
    Done.
    </p>
    </body>
    </html>
    =============== =====
    Now, I would like to find all <pre> tags of the "text" class and
    1. change the class value
    2. append another node ( <textarea> )
    3. surround the both nodes by a third one ( <form> )
    =============== ===
    <html>
    <body>
    <p>
    This is some text.
    <p>

    <form>
    <pre class="text2">
    a = 6*7
    print a
    </pre>
    <textarea cols=80 name="code">
    </textarea>
    <input type="submit"></input>
    </form>

    <p>
    Done.
    </p>
    </body>
    </html>
    ===============

    Any help would be appreciated.
    André

  • Fredrik Lundh

    #2
    Re: Using elementtree: replacing nodes

    André wrote:
    [color=blue]
    > I've started using elementtree and don't understand how to use it to
    > manipulate and replace nodes. I know how to do this using a simple,
    > but inefficient parser I wrote, but I'd rather learn to use a better
    > tool - especially as it is to be added to the standard library.[/color]
    [color=blue]
    > Now, I would like to find all <pre> tags of the "text" class and[/color]

    for pre in elem.getiterato r("pre"):

    or

    for pre in elem.findall(".//pre"):
    [color=blue]
    > 1. change the class value[/color]

    pre.set("class" , "value")
    [color=blue]
    > 2. append another node ( <textarea> )
    > 3. surround the both nodes by a third one ( <form> )[/color]

    or in other words,

    2. replace the <pre> with a <form> element that contains some
    new contents derived from the old element

    # 1) build the new form
    form = Element("form")
    e = SubElement(form , "pre")
    e.set("class", "text2")
    e.text = pre.text
    e = SubElement(form , "textarea", cols=80, name="code")
    e = SubElement(form , "input", type="submit")

    # 2) mutate the pre element
    pre.clear()
    pre.tag = "form"
    pre[:] = [form]

    for harder cases, a common pattern is:

    for parent in elem.getiterato r():
    for index, child in enumerate(paren t.findall("pre" )):
    # the code in here can manipulate parent[i] and child

    another approach is to build a parent map; see the parent_map code
    at



    </F>



    Comment

    • André

      #3
      Re: Using elementtree: replacing nodes

      Fredrik Lundh wrote:[color=blue]
      > André wrote:
      >[color=green]
      > > I've started using elementtree and don't understand how to use it to
      > > manipulate and replace nodes.[/color][/color]

      [snip]
      It was mostly the following step which I couldn`t figure out...
      [color=blue]
      > # 2) mutate the pre element
      > pre.clear()
      > pre.tag = "form"
      > pre[:] = [form]
      >[/color]
      [snip]
      [color=blue]
      > another approach is to build a parent map; see the parent_map code
      > at
      >
      > http://effbot.org/zone/element.htm#the-element-type
      > [/color]


      Thanks!
      [color=blue]
      > </F>[/color]

      Comment

      Working...