1

I parse a file in python

tree = ET.parse('existing.xml')

Add some xml Elements in memory into the XML Structure

NodeList = tree.findall(".//NodeList")

NodeList_WeWant = buildingNodeList[0]

for member in aList:
    ET.SubElement(NodeList_WeWant,member)

Write back to Disk

tree.write("output.sbp", encoding="utf-16")

But I get

Traceback (most recent call last):
  File "runonreal.py", line 156, in <module>
    tree.write("output.sbp", encoding="utf-16")
  File "C:\Python340\lib\xml\etree\ElementTree.py", line 775, in write
    qnames, namespaces = _namespaces(self._root, default_namespace)
  File "C:\Python340\lib\xml\etree\ElementTree.py", line 887, in _namespaces
    _raise_serialization_error(tag)
  File "C:\Python340\lib\xml\etree\ElementTree.py", line 1059, in _raise_serialization_error
    "cannot serialize %r (type %s)" % (text, type(text).__name__)
TypeError: cannot serialize <Element 'BuildingNodeBase' at 0x099421B0> (type Element)

Edit. A Simple Replication of Error. See Below

My basic xml

<?xml version="1.0" encoding="UTF-8"?>
<family>
  <person>
  <id>100</id>
  <name>Shorn</name>
  <height>5.8</height>
  </person>
  <person>
  <id>101</id>
  </person>
</family>

Python Script

import xml.etree.ElementTree as ET
from copy import deepcopy

tree = ET.parse('basic.xml')

root = tree.getroot()

cloneFrom = tree.findall(".//person[name='Shorn']")

cloneTo =  tree.findall(".//person[id='101']")

cloneTo = deepcopy(cloneFrom)

ET.SubElement(root,cloneTo)

tree.write("output.xml", encoding="utf-16")

This errors out enter image description here

And this is my expected output.xml . Person Node should be cloned to another person node and written back to disk.

<?xml version="1.0" encoding="UTF-16"?>
<family>
  <person>
  <id>100</id>
  <name>Shorn</name>
  <height>5.8</height>
  </person>
  <person>
  <id>100</id>
  <name>Shorn</name>
  <height>5.8</height>
  </person>
</family>
0

1 Answer 1

2

There are some problems here:

  • findall() returns a list, not a single element.
  • SubElement expects a string, not an Element object, as the second argument.
  • The element with id='101' is not removed.

Here is code that works for me (tested with Python 3.6.1):

import xml.etree.ElementTree as ET
from copy import deepcopy

tree = ET.parse('basic.xml')
root = tree.getroot()

remove = tree.find(".//person[id='101']")
cloneFrom = tree.find(".//person[name='Shorn']")

root.remove(remove)
root.append(deepcopy(cloneFrom))

tree.write("output.xml", encoding="utf-16")

This is what output.xml looks like:

<?xml version='1.0' encoding='utf-16'?>
<family>
  <person>
    <id>100</id>
    <name>Shorn</name>
    <height>5.8</height>
  </person>
  <person>
    <id>100</id>
    <name>Shorn</name>
    <height>5.8</height>
  </person>
  </family>
Sign up to request clarification or add additional context in comments.

Comments

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.