From eaddb643f02d75811f57ffa75bf8ac57a120cb96 Mon Sep 17 00:00:00 2001 From: Carol Flower Date: Mon, 27 Jan 2020 15:53:33 +0100 Subject: [PATCH 1/3] Fix for 'single element array' issue. --- xmljson/__init__.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/xmljson/__init__.py b/xmljson/__init__.py index 7efa16c..25c4802 100644 --- a/xmljson/__init__.py +++ b/xmljson/__init__.py @@ -352,6 +352,44 @@ def data(self, root): return self.dict([(unicode(root.tag), value)]) +# Converts XML to JSON using the Spark Convention. +# Specified tags are considered as single element arrays if there is only one child +class Spark(XMLData): + '''Converts between XML and data using the Spark convention''' + def __init__(self, **kwargs): + super(Spark, self).__init__(**kwargs) + + # Param 'single_element_array_tags' specifies the tags to be treated as sigle element arrays + def data(self, root, preserve_root=False, single_element_array_tags=[]): + '''Convert etree.Element into a dictionary''' + # If preserve_root is False, return the root element. This is easiest + # done by wrapping the XML in a dummy root element that will be ignored. + if preserve_root: + new_root = root.makeelement('dummy_root', {}) + new_root.insert(0, root) + root = new_root + # If no children, just return the text + children = [node for node in root if isinstance(node.tag, basestring)] + + if len(children) == 0: + #For specified tags data is formatted as per 'single element array' + if root.tag in single_element_array_tags: + return [root.text] + return self._fromstring(root.text) + + # Element names become object properties + count = Counter(child.tag for child in children) + result = self.dict() + for child in children: + #For specified tags data is formatted as per 'single element array' + if child.tag in single_element_array_tags: + result.setdefault(child.tag, self.list()).append(self.data(child,single_element_array_tags=single_element_array_tags)) + elif count[child.tag] == 1: + result[child.tag] = self.data(child,single_element_array_tags=single_element_array_tags) + else: + result.setdefault(child.tag, self.list()).append(self.data(child,single_element_array_tags=single_element_array_tags)) + + return result abdera = Abdera() badgerfish = BadgerFish() @@ -359,3 +397,4 @@ def data(self, root): gdata = GData() parker = Parker() yahoo = Yahoo() +spark = Spark() \ No newline at end of file From cc1b19cf8d4249da988bcad8059efcf982e3d713 Mon Sep 17 00:00:00 2001 From: Carol Flower Date: Mon, 27 Jan 2020 16:31:33 +0100 Subject: [PATCH 2/3] Fix for 'single element array' issue. --- xmljson/__init__.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/xmljson/__init__.py b/xmljson/__init__.py index 25c4802..ac12c1f 100644 --- a/xmljson/__init__.py +++ b/xmljson/__init__.py @@ -352,7 +352,8 @@ def data(self, root): return self.dict([(unicode(root.tag), value)]) -# Converts XML to JSON using the Spark Convention. + +# Converts XML to JSON using the Spark Convention. # Specified tags are considered as single element arrays if there is only one child class Spark(XMLData): '''Converts between XML and data using the Spark convention''' @@ -370,9 +371,8 @@ def data(self, root, preserve_root=False, single_element_array_tags=[]): root = new_root # If no children, just return the text children = [node for node in root if isinstance(node.tag, basestring)] - if len(children) == 0: - #For specified tags data is formatted as per 'single element array' + # For specified tags data is formatted as per 'single element array' if root.tag in single_element_array_tags: return [root.text] return self._fromstring(root.text) @@ -381,20 +381,24 @@ def data(self, root, preserve_root=False, single_element_array_tags=[]): count = Counter(child.tag for child in children) result = self.dict() for child in children: - #For specified tags data is formatted as per 'single element array' + #For specified tags data is formatted as per 'single element array' if child.tag in single_element_array_tags: - result.setdefault(child.tag, self.list()).append(self.data(child,single_element_array_tags=single_element_array_tags)) + result.setdefault(child.tag, self.list()) + .append(self.data(child,single_element_array_tags=single_element_array_tags)) elif count[child.tag] == 1: - result[child.tag] = self.data(child,single_element_array_tags=single_element_array_tags) + result[child.tag] = self + .data(child,single_element_array_tags=single_element_array_tags) else: - result.setdefault(child.tag, self.list()).append(self.data(child,single_element_array_tags=single_element_array_tags)) + result.setdefault(child.tag, self.list()) + .append(self.data(child,single_element_array_tags=single_element_array_tags)) return result + abdera = Abdera() badgerfish = BadgerFish() cobra = Cobra() gdata = GData() parker = Parker() yahoo = Yahoo() -spark = Spark() \ No newline at end of file +spark = Spark() From 0b62527bd5e6f44e79c6dd6b57074c72b3eadd78 Mon Sep 17 00:00:00 2001 From: Carol Flower Date: Mon, 27 Jan 2020 16:51:10 +0100 Subject: [PATCH 3/3] Code formatting for Travis build --- xmljson/__init__.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/xmljson/__init__.py b/xmljson/__init__.py index ac12c1f..2c1c70f 100644 --- a/xmljson/__init__.py +++ b/xmljson/__init__.py @@ -175,18 +175,21 @@ def data(self, root): class BadgerFish(XMLData): '''Converts between XML and data using the BadgerFish convention''' + def __init__(self, **kwargs): super(BadgerFish, self).__init__(attr_prefix='@', text_content='$', **kwargs) class GData(XMLData): '''Converts between XML and data using the GData convention''' + def __init__(self, **kwargs): super(GData, self).__init__(text_content='$t', **kwargs) class Yahoo(XMLData): '''Converts between XML and data using the Yahoo convention''' + def __init__(self, **kwargs): kwargs.setdefault('xml_fromstring', False) super(Yahoo, self).__init__(text_content='content', simple_text=True, **kwargs) @@ -194,6 +197,7 @@ def __init__(self, **kwargs): class Parker(XMLData): '''Converts between XML and data using the Parker convention''' + def __init__(self, **kwargs): super(Parker, self).__init__(**kwargs) @@ -225,6 +229,7 @@ def data(self, root, preserve_root=False): class Abdera(XMLData): '''Converts between XML and data using the Abdera convention''' + def __init__(self, **kwargs): super(Abdera, self).__init__(simple_text=True, text_content=True, **kwargs) @@ -271,6 +276,7 @@ def data(self, root): # https://github.com/datacenter/cobra/blob/master/cobra/internal/codec/jsoncodec.py class Cobra(XMLData): '''Converts between XML and data using the Cobra convention''' + def __init__(self, **kwargs): super(Cobra, self).__init__(simple_text=True, text_content=True, xml_fromstring=False, **kwargs) @@ -357,6 +363,7 @@ def data(self, root): # Specified tags are considered as single element arrays if there is only one child class Spark(XMLData): '''Converts between XML and data using the Spark convention''' + def __init__(self, **kwargs): super(Spark, self).__init__(**kwargs) @@ -381,16 +388,16 @@ def data(self, root, preserve_root=False, single_element_array_tags=[]): count = Counter(child.tag for child in children) result = self.dict() for child in children: - #For specified tags data is formatted as per 'single element array' + # For specified tags data is formatted as per 'single element array' if child.tag in single_element_array_tags: - result.setdefault(child.tag, self.list()) - .append(self.data(child,single_element_array_tags=single_element_array_tags)) + result.setdefault(child.tag, self.list()).append(self.data( + child, single_element_array_tags=single_element_array_tags)) elif count[child.tag] == 1: - result[child.tag] = self - .data(child,single_element_array_tags=single_element_array_tags) + result.setdefault(child.tag, self.list()).append(self.data( + child, single_element_array_tags=single_element_array_tags)) else: - result.setdefault(child.tag, self.list()) - .append(self.data(child,single_element_array_tags=single_element_array_tags)) + result.setdefault(child.tag, self.list()).append(self.data( + child, single_element_array_tags=single_element_array_tags)) return result