编码和解码xml字符串中的字节

时间:2019-11-27 03:32:58

标签: python python-3.x xml byte

我正在寻找一种在xml文件中写入和读取字节数据的方法。我希望xml文件易于阅读,因此我想避免使用base64编码或类似的东西。我想我可以做这样的事情。如果我有一个字符串b'abc < ABC\x04&',需要将其放入标记<node>中,那么我会将其写为

<node>abc &lt; ABC&#x04;&amp;</node>

是否有一种方法可以使这种编码与python3中的任何xml库一起使用?我更喜欢lxml,但这不是必须的。

说明:当我编写xml文件时,字符串最初的类型为bytes,例如b'abc < ABC\x04&'。在很多情况下,它们仅包含字母数字的ascii字符,我想这样将它们写入xml。我想将其他字节编码为十六进制值,因此仍然可以轻松理解它们。而且我想将>&之类的字符编码为&gt;&amp;(或者也作为十六进制值),以避免使用<![CDATA[<]]>。读取字符串时,我希望尽可能将它们转换回b'...'

1 个答案:

答案 0 :(得分:1)

我很确定没有内置功能可以完全准确您的要求

我认为您能做的最好就是迭代字符并“修复”每个字符(请参见我认为完整的示例)

try: # python2
  from htmlentitydefs import codepoint2name
except: # python3
  from html.entities import codepoint2name

def encode_xml(c):
  # return the character or its &#XX; or &entity; representation
  ascii_val = ord(c)
  known_entity =  codepoint2name.get(ascii_val,None)
  if known_entity: # this is a named codepoint
    return "&%s;"%(known_entity,)  
  # printable characters are ascii values [32..127] inclusive
  is_normal_character =  32 <= ascii_val <= 127
  if is_normal_character:
      return c
  return hex(ascii_val).replace("0x","&#")+";"


def make_xml_entity_string(s):
  return "".join(encode_xml(c) for c in s)

print("R:", make_xml_entity_string( 'abc < ABC\x14\xF2&'))

然后您可以...以大致相同的方式进行操作(尽管这次利用了正则表达式)

try: # python2  
  from htmlentitydefs import name2codepoint
except: # python3
  from html.entities import name2codepoint
import re

def decode_xml_replacer(match):
  name=match.group(1);
  if(name.startswith("#")):
    return chr(int(name[1:],16))
  return chr(name2codepoint.get(name,'?'))

def decode_xml_string(s):
  return re.sub("&(.*?);",decode_xml_replacer,s)

...请注意,这不适用于我认为大于255的代码点

相关问题