diff --git a/.travis.yml b/.travis.yml
index c380f18..8a04e37 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,6 +4,7 @@ python:
- 2.7
- 3.2
- 3.3
+ - 3.8
install:
- pip install -r requirements.txt --use-mirrors
script:
diff --git a/simplexml/core.py b/simplexml/core.py
index de8af95..a1752d0 100644
--- a/simplexml/core.py
+++ b/simplexml/core.py
@@ -14,6 +14,11 @@
import re
from xml.dom.minidom import getDOMImplementation, parseString
+def exclude_attrs_nodes_from_dict(data):
+ if type(data) == dict:
+ return {x: data[x] for x in data if x != '_attrs'}
+ return data
+
def element_from_dict(document, elRoot, data):
if type(data) == list:
@@ -30,22 +35,23 @@ def element_from_dict(document, elRoot, data):
if '_attrs' in v:
for name,value in v["_attrs"].items():
elem.setAttribute(name, str(value))
- del(v["_attrs"])
-
+
if '_value' in v:
value = v.get('_value')
textNode = document.createCDATASection(value) if isinstance(value, str) and re.search("[\<\>\&]", value) else document.createTextNode(str(value))
elem.appendChild(textNode)
+
else:
- element_from_dict(document, elem, v)
+ element_from_dict(document, elem, exclude_attrs_nodes_from_dict(v))
elRoot.appendChild(elem)
+
elif isinstance(v, list):
if k.endswith("s"):
elem = document.createElement(k)
for item in v:
elItem = document.createElement(k[0:len(k)-1])
- element_from_dict(document, elItem, item)
+ element_from_dict(document, elItem, exclude_attrs_nodes_from_dict(item))
elem.appendChild(elItem)
elRoot.appendChild(elem)
else:
@@ -54,14 +60,13 @@ def element_from_dict(document, elRoot, data):
if '_attrs' in item:
for name,value in item["_attrs"].items():
elItem.setAttribute(name, str(value))
- del(item["_attrs"])
if '_value' in item:
value = item.get('_value')
textNode = document.createCDATASection(value) if isinstance(value, str) and re.search("[\<\>\&]", value) else document.createTextNode(str(value))
elItem.appendChild(textNode)
else:
- element_from_dict(document, elItem, item)
+ element_from_dict(document, elItem, exclude_attrs_nodes_from_dict(item))
elRoot.appendChild(elItem)
@@ -126,9 +131,23 @@ def dumps(data):
if type(rootValue) == dict and '_attrs' in rootValue:
for name,value in rootValue["_attrs"].items():
rootNode.setAttribute(name, value)
- del(rootValue["_attrs"])
+
+ if type(rootValue) == dict and '_value' in rootValue:
+ # Handles case where root node contains single text node - allowing for attribute definition and CDATA handling
+ value = rootValue.get('_value')
+ textNode = document.createCDATASection(value) if isinstance(value, str) and re.search("[\<\>\&]", value) else document.createTextNode(str(value))
+ rootNode.appendChild(textNode)
+ # Text or CDATA node cannot have children
+ return document.toxml()
+
+
+ if type(rootValue) == str:
+ # Handles case where root node contains single text node - simple case not allowing for attribute definition
+ text = document.createTextNode(rootValue)
+ rootNode.appendChild(text)
+ return document.toxml()
- element_from_dict(document, rootNode, rootValue)
+ element_from_dict(document, rootNode, exclude_attrs_nodes_from_dict(rootValue))
return document.toxml()
diff --git a/tests/test_core.py b/tests/test_core.py
index d0fc2fa..b685f41 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -108,3 +108,22 @@ def test_can_dumps_with_first_node_list():
response = simplexml.dumps(sometag)
assert 'Should Be NomeShould Be Nome' in response
+
+def test_can_dumps_with_single_simple_node():
+ sometag = {'someTag': 'Should be Name'}
+ response = simplexml.dumps(sometag)
+
+ assert 'Should be Name' in response
+
+def test_can_dumps_with_root_node_containing_text_node():
+ sometag = {'someTag': {'_attrs': {'id': '1'}, '_value': 'Should be value'}}
+ response = simplexml.dumps(sometag)
+
+ assert 'Should be value' in response
+
+def test_repeated_calls_to_dumps_preserves_dict_attrs():
+ sometag = {'someTag': {'_attrs': {'id': '1'}, '_value': 'Should be value'}}
+ response1 = simplexml.dumps(sometag)
+ response2 = simplexml.dumps(sometag)
+
+ assert 'Should be value' in response2
diff --git a/tox.ini b/tox.ini
index 299fa89..6427405 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = py26,py27,py33
+envlist = py26,py27,py33,py38
[testenv]
deps=
nose==1.1.2