[Kimchi-devel] [PATCH 1/3] xml parser: Add a parser to xmlutils

Sheldon shaohef at linux.vnet.ibm.com
Thu Jan 9 14:01:55 UTC 2014


On 01/09/2014 06:32 PM, lvroyce at linux.vnet.ibm.com wrote:
> From: Royce Lv <lvroyce at linux.vnet.ibm.com>
>
> Add an xml parser to xmlutils.py to deal with the increasing need
> in kimchi to converse an xml to dict.
I have suggested to adopt this patch several times. I need xml2dic.
But seems this patch is not welcome.
So Adam filed a issue about "generate and manipulate XML documents" 4 
months ago.
https://github.com/kimchi-project/kimchi/issues/124
Also we has give up libvirt-gobject.

and now we can get a python third module on some distros.
on rhel6.5 and my F20
$ sudo yum search python-xmltodict
python-xmltodict.noarch : Makes working with XML feel like you are 
working with JSON


we need xml2dict and dict2xml.
discuss with Mark about "generate and manipulate XML documents".
we think maybe lxml is good for us.

$ sudo yum search python-lxml
python-lxml-docs.noarch : Documentation for python-lxml
python-lxml.x86_64 : ElementTree-like Python bindings for libxml2 and 
libxslt

you can consider lxml.

>
> Signed-off-by: Bing Bu Cao <mars at linux.vnet.ibm.com>
> Signed-off-by: Royce Lv <lvroyce at linux.vnet.ibm.com>
> ---
>   src/kimchi/exception.py |  4 ++++
>   src/kimchi/xmlutils.py  | 54 ++++++++++++++++++++++++++++++++++++++++++++++---
>   2 files changed, 55 insertions(+), 3 deletions(-)
>
> diff --git a/src/kimchi/exception.py b/src/kimchi/exception.py
> index bff0a18..623e6b3 100644
> --- a/src/kimchi/exception.py
> +++ b/src/kimchi/exception.py
> @@ -43,3 +43,7 @@ class InvalidOperation(Exception):
>
>   class IsoFormatError(Exception):
>       pass
> +
> +
> +class ParseError(Exception):
> +    pass
> diff --git a/src/kimchi/xmlutils.py b/src/kimchi/xmlutils.py
> index 51ff0ec..f94db30 100644
> --- a/src/kimchi/xmlutils.py
> +++ b/src/kimchi/xmlutils.py
> @@ -23,7 +23,11 @@
>   import libxml2
>
>
> -from xml.etree import ElementTree
> +from collections import defaultdict
> +from xml.etree import ElementTree as ET
> +
> +
> +from kimchi.exception import ParseError
>
>
>   def xpath_get_text(xml, expr):
> @@ -36,7 +40,51 @@ def xpath_get_text(xml, expr):
>
>
>   def xml_item_update(xml, xpath, value):
> -    root = ElementTree.fromstring(xml)
> +    root = ET.fromstring(xml)
>       item = root.find(xpath)
>       item.text = value
> -    return ElementTree.tostring(root, encoding="utf-8")
> +    return ET.tostring(root, encoding="utf-8")
> +
> +
> +def xml_to_dict(xml, fromstring=True):
> +    try:
> +        if fromstring:
> +            t = ET.fromstring(xml)
> +        else:
> +            t = ET.parse(xml).getroot()
> +    except ET.ParseError:
> +            raise ParseError("XML parse failed, invalid XML file")
> +    return _etree_to_dict(t)
> +
> +
> +def _etree_to_dict(t):
> +    # Convert an etree object to dict
> +    d = {t.tag: {} if t.attrib else None}
> +    children = list(t)
> +    td = {}
> +    if children:
> +        dd = defaultdict(list)
> +        #if has subelement, iteration as it's a new element
> +        for dc in map(_etree_to_dict, children):
> +            for k, v in dc.iteritems():
> +                dd[k].append(v)
> +                for k, v in dd.iteritems():
> +                    if len(v) == 1:
> +                        va = v[0]
> +                    else:
> +                        va = v
> +                    td.update({k: va})
> +                    d[t.tag] = td
> +
> +    #prepend '@' to attr and '#' to value
> +    if t.attrib:
> +        d[t.tag].update((k, v) for k, v in t.attrib.iteritems())
> +    if t.text:
> +        text = t.text.strip()
> +        if children or t.attrib:
> +            if text:
> +                d[t.tag]['#value'] = text
> +        else:
> +            d[t.tag] = text
> +
> +    return d


-- 
Thanks and best regards!

Sheldon Feng(冯少合)<shaohef at linux.vnet.ibm.com>
IBM Linux Technology Center




More information about the Kimchi-devel mailing list