diff --git a/basic/regex/resample.py b/basic/regex/re_search.py similarity index 97% rename from basic/regex/resample.py rename to basic/regex/re_search.py index 2120be7..56d8437 100644 --- a/basic/regex/resample.py +++ b/basic/regex/re_search.py @@ -1,8 +1,8 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- """ - Topic: sample - Desc : 各种正则式例子 + Topic: 简单的正则式搜索,包括分组捕获 + Desc : 正则式例子 建议阅读Jeffrey E. F. Friedl编写的《精通正则表达式》 (Mastering Regular Expression) """ diff --git a/cookbook/c06/p05_dict_toxml.py b/cookbook/c06/p05_dict_toxml.py new file mode 100644 index 0000000..0363100 --- /dev/null +++ b/cookbook/c06/p05_dict_toxml.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +""" +Topic: 字典转换成XML格式 +Desc : +""" +from xml.etree.ElementTree import Element +from xml.etree.ElementTree import tostring + + +def dict_to_xml(tag, d): + """ + Turn a simple dict of key/value pairs into XML + """ + elem = Element(tag) + for key, val in d.items(): + child = Element(key) + child.text = str(val) + elem.append(child) + return elem + +if __name__ == '__main__': + r = dict_to_xml('root', {'1':'22', '3':'444'}) + print(r) + print(tostring(r)) + r.set('_id','1234') + print(tostring(r)) + + + diff --git a/source/c06/p05_turning_dictionary_into_xml.rst b/source/c06/p05_turning_dictionary_into_xml.rst index 31b9d19..5ff0337 100644 --- a/source/c06/p05_turning_dictionary_into_xml.rst +++ b/source/c06/p05_turning_dictionary_into_xml.rst @@ -5,14 +5,113 @@ ---------- 问题 ---------- -todo... +你想使用一个Python字典存储数据,并将它转换成XML格式。 + +| ---------- 解决方案 ---------- -todo... +尽管 ``xml.etree.ElementTree`` 库通常用来做解析工作,其实它也可以创建XML文档。 +例如,考虑如下这个函数: + +.. code-block:: python + + from xml.etree.ElementTree import Element + + def dict_to_xml(tag, d): + ''' + Turn a simple dict of key/value pairs into XML + ''' + elem = Element(tag) + for key, val in d.items(): + child = Element(key) + child.text = str(val) + elem.append(child) + return elem + +下面是一个使用例子: + +.. code-block:: python + + >>> s = { 'name': 'GOOG', 'shares': 100, 'price':490.1 } + >>> e = dict_to_xml('stock', s) + >>> e + + >>> + +转换结果是一个 ``Element`` 实例。对于I/O操作,使用 ``xml.etree.ElementTree`` 中的 ``tostring()`` +函数很容易就能将它转换成一个字节字符串。例如: + +.. code-block:: python + + >>> from xml.etree.ElementTree import tostring + >>> tostring(e) + b'490.1100GOOG' + >>> + +如果你想给某个元素添加属性值,可以使用 ``set()`` 方法: + +.. code-block:: python + + >>> e.set('_id','1234') + >>> tostring(e) + b'490.1100GOOG + ' + >>> + +如果你还想保持元素的顺序,可以考虑构造一个 ``OrderedDict`` 来代替一个普通的字典。请参考1.7小节。 + +| ---------- 讨论 ---------- -todo... \ No newline at end of file +当创建XML的时候,你被限制只能构造字符串类型的值。例如: + +.. code-block:: python + + def dict_to_xml_str(tag, d): + ''' + Turn a simple dict of key/value pairs into XML + ''' + parts = ['<{}>'.format(tag)] + for key, val in d.items(): + parts.append('<{0}>{1}'.format(key,val)) + parts.append(''.format(tag)) + return ''.join(parts) + +问题是如果你手动的去构造的时候可能会碰到一些麻烦。例如,当字典的值中包含一些特殊字符的时候会怎样呢? + +.. code-block:: python + + >>> d = { 'name' : '' } + + >>> # String creation + >>> dict_to_xml_str('item',d) + '' + + >>> # Proper XML creation + >>> e = dict_to_xml('item',d) + >>> tostring(e) + b'<spam>' + >>> + +注意到程序的后面那个例子中,字符 '<' 和 '>' 被替换成了 ``<`` 和 ``>`` + +下面仅供参考,如果你需要手动去转换这些字符, +可以使用 ``xml.sax.saxutils`` 中的 ``escape()`` 和 ``unescape()`` 函数。例如: + +.. code-block:: python + + >>> from xml.sax.saxutils import escape, unescape + >>> escape('') + '<spam>' + >>> unescape(_) + '' + >>> + +除了能创建正确的输出外,还有另外一个原因推荐你创建 ``Element`` 实例而不是字符串, +那就是使用字符串组合构造一个更大的文档并不是那么容易。 +而 ``Element`` 实例可以不用考虑解析XML文本的情况下通过多种方式被处理。 +也就是说,你可以在一个高级数据结构上完成你所有的操作,并在最后以字符串的形式将其输出。