了解如何引用XML字符串以使用Python的ElementTree进行序列化

时间:2016-01-09 20:46:09

标签: python string elementtree

我的规格:

  1. Python 3.4.3
  2. Windows 7
  3. IDE是Jupyter笔记本
  4. 我所引用的内容:

    1. how-to-properly-escape-single-and-double-quotes
    2. python-escaping-strings-for-use-in-xml
    3. escaping-characters-in-a-xml-file-with-python
    4. 下面分别是下面的数据和脚本(我尝试过使用Sax和ElementTree序列化列'E'的变体):

      数据

      A,B,C,D,E,F,G,H,I,J
      "3","8","1","<Request TransactionID="3" RequestType="FOO"><InstitutionISO /><CallID>23</CallID><MemberID>12</MemberID><MemberPassword /><RequestData><AccountNumber>2</AccountNumber><AccountSuffix>85</AccountSuffix><AccountType>S</AccountType><MPIAcctType>Checking</MPIAcctType><TransactionCount>10</TransactionCount></RequestData></Request>","<Response TransactionID="2" RequestType="HoldInquiry"><ShareList>0000',0001,0070,</ShareList></Response>","1967-12-25 22:18:13.471000","2005-12-25 22:18:13.768000","2","70","0"
      

      脚本

      #!/usr/bin/python
      # -*-  coding: utf-8 -*-
      import os.path
      import sys
      import csv
      from io import StringIO 
      import xml.etree.cElementTree as ElementTree
      from xml.etree.ElementTree import XMLParser
      import xml
      import xml.sax
      from xml.sax import ContentHandler
      
      class MyHandler(xml.sax.handler.ContentHandler):
          def __init__(self):
              self._charBuffer = []
              self._result = []
      
          def _getCharacterData(self):
              data = ''.join(self._charBuffer).strip()
              self._charBuffer = []
              return data.strip() #remove strip() if whitespace is important
      
          def parse(self, f):
              xml.sax.parse(f, self)
              return self._result
      
      
          def characters(self, data):
              self._charBuffer.append(data)
      
          def startElement(self, name, attrs):
              if name == 'Response':
                  self._result.append({})
      
          def endElement(self, name):
              if not name == 'Response': self._result[-1][name] = self._getCharacterData()
      
      def read_data(path):
          with open(path, 'rU', encoding='utf-8') as data:
              reader = csv.DictReader(data, delimiter =',', quotechar="'", skipinitialspace=True)
              for row in reader:
                  yield row
      
      if __name__ == "__main__":
          empty = ''
          Response = 'sample.csv'
          for idx, row in enumerate(read_data(Response)):
              if idx > 10: break
              data = row['E']
              print(data) # The before
              data = data[1:-1]
              data = ""'{}'"".format(data)
              print(data) # Sanity check 
      #         data = '<Response TransactionID="2" RequestType="HoldInquiry"><ShareList>0000',0001,0070,</ShareList></Response>'
              try:
                  root = ElementTree.XML(data)
      #             print(root)
              except StopIteration:
                  raise
                  pass
      #         xmlstring = StringIO(data)
      #         print(xmlstring)
      #         Handler = MyHandler().parse(xmlstring)
      

      具体来说,由于CSV文件中的引用(这是我无法控制的),我不得不求助于切割字符串(第51行)然后格式化它(第52行)。

      然而,上述尝试的打印如下:

      "<Response TransactionID="2" RequestType="HoldInquiry"><ShareList>0000'
      <Response TransactionID="2" RequestType="HoldInquiry"><ShareList>0000
      
        File "<string>", line unknown
      ParseError: no element found: line 1, column 69
      

      有趣的是 - 如果我分配变量“data”(如第54行所示),我会收到:

        File "<ipython-input-80-7357c9272b92>", line 56
      data = '<Response TransactionID="2" RequestType="HoldInquiry"><ShareList>0000',0001,0070,</ShareList></Response>'
                                                                                        ^ 
      SyntaxError: invalid token
      

      我寻求有关如何利用最多Pythonic手段解决问题的反馈和信息。理想情况下,是否有一种可以利用ElementTree的方法。提前感谢您的反馈和指导。

1 个答案:

答案 0 :(得分:1)

似乎你的格式错误(好的,引用不当)的csv数据。

如果csv文件超出您的控制范围,我建议不要使用csv阅读器来阅读它们,
相反 - 如果您可以依赖正确引用的每个字段 - 自己拆分。

with open(Response, 'rU', encoding='utf-8') as data:
    separated = data.read().split('","')
    try:
        x = ElementTree.XML(separated[3])
        print(x)
        xml.etree.ElementTree.dump(x)
        y = ElementTree.XML(separated[4])
        xml.etree.ElementTree.dump(y)
    except Exception as e:
       print(e)

输出

<Element 'Request' at 0xb6d973b0>
<Request RequestType="FOO" TransactionID="3"><InstitutionISO /><CallID>23</CallID><MemberID>12</MemberID><MemberPassword /><RequestData><AccountNumber>2</AccountNumber><AccountSuffix>85</AccountSuffix><AccountType>S</AccountType><MPIAcctType>Checking</MPIAcctType><TransactionCount>10</TransactionCount></RequestData></Request>
<Response RequestType="HoldInquiry" TransactionID="2"><ShareList>0000',0001,0070,</ShareList></Response>