복붙노트

[PYTHON] XML 파일을 파이썬 객체로 파싱

PYTHON

XML 파일을 파이썬 객체로 파싱

나는 다음과 같은 XML 파일을 가지고있다 :

<encspot>
  <file>
   <Name>some filename.mp3</Name>
   <Encoder>Gogo (after 3.0)</Encoder>
   <Bitrate>131</Bitrate>
   <Mode>joint stereo</Mode>
   <Length>00:02:43</Length>
   <Size>5,236,644</Size>
   <Frame>no</Frame>
   <Quality>good</Quality>
   <Freq.>44100</Freq.>
   <Frames>6255</Frames>
   ..... and so forth ......
  </file>
  <file>....</file>
</encspot>

나는 파이썬 객체로 그것을 읽고 싶다. 사전 목록과 같다. 마크 업은 절대적으로 고정되어 있으므로 정규 표현식을 사용하도록 유혹됩니다 (나는이를 사용하는 것이 좋습니다). 그러나 누군가가 쉽게 regexes를 피할 수있는 방법을 알고 있는지 확인할 것입니다. SAX 나 다른 구문 분석에 대한 경험이별로 없지만 배우려합니다.

파이썬에서 정규 표현식없이 이것이 어떻게 빨리 수행되는지 보여 주길 고대하고 있습니다. 당신의 도움을 주셔서 감사합니다!

해결법

  1. ==============================

    1.내가 사랑하는 SD Chargers 모자는 정규식이 이보다 더 쉽다고 생각한다면 당신에게 달려 있습니다.

    내가 사랑하는 SD Chargers 모자는 정규식이 이보다 더 쉽다고 생각한다면 당신에게 달려 있습니다.

    #!/usr/bin/env python
    import xml.etree.cElementTree as et
    
    sxml="""
    <encspot>
      <file>
       <Name>some filename.mp3</Name>
       <Encoder>Gogo (after 3.0)</Encoder>
       <Bitrate>131</Bitrate>
      </file>
      <file>
       <Name>another filename.mp3</Name>
       <Encoder>iTunes</Encoder>
       <Bitrate>128</Bitrate>  
      </file>
    </encspot>
    """
    tree=et.fromstring(sxml)
    
    for el in tree.findall('file'):
        print '-------------------'
        for ch in el.getchildren():
            print '{:>15}: {:<30}'.format(ch.tag, ch.text) 
    
    print "\nan alternate way:"  
    el=tree.find('file[2]/Name')  # xpath
    print '{:>15}: {:<30}'.format(el.tag, el.text)  
    

    산출:

    -------------------
               Name: some filename.mp3             
            Encoder: Gogo (after 3.0)              
            Bitrate: 131                           
    -------------------
               Name: another filename.mp3          
            Encoder: iTunes                        
            Bitrate: 128                           
    
    an alternate way:
               Name: another filename.mp3  
    

    정규식에 대한 귀하의 관심이 간결 해지면 다음과 같이 데이터 구조를 생성하는 이해하기 어려운 목록 이해가 있습니다.

    [(ch.tag,ch.text) for e in tree.findall('file') for ch in e.getchildren()]
    

    의 XML 자식의 튜플 목록을 문서 순서로 작성합니다.

    [('Name', 'some filename.mp3'), 
     ('Encoder', 'Gogo (after 3.0)'), 
     ('Bitrate', '131'), 
     ('Name', 'another filename.mp3'), 
     ('Encoder', 'iTunes'), 
     ('Bitrate', '128')]
    

    몇 줄을 더 추가하고 조금 더 생각해 보면 분명 ElementTree를 사용하여 XML에서 원하는 모든 데이터 구조를 만들 수 있습니다. 이것은 파이썬 배포본의 일부입니다.

    편집하다

    코드 골프가 켜져 있습니다!

    [{item.tag: item.text for item in ch} for ch in tree.findall('file')] 
    [ {'Bitrate': '131', 
       'Name': 'some filename.mp3', 
       'Encoder': 'Gogo (after 3.0)'}, 
      {'Bitrate': '128', 
       'Name': 'another filename.mp3', 
       'Encoder': 'iTunes'}]
    

    XML에 파일 섹션 만 있으면 골프를 선택할 수 있습니다. XML에 다른 태그, 다른 섹션이있는 경우 어린이가 속한 섹션을 고려해야하며 findall을 사용해야합니다

    Effbot.org의 ElementTree에 대한 자습서가 있습니다.

  2. ==============================

    2.ElementTree를 사용하십시오. pyexpat와 같은 구문 분석 전용 가제트가 필요하지 않거나 원하지 않는다면 ... ElementTree를 부분적으로 만 또는 다시 제대로 만들지 않게 될 것입니다.

    ElementTree를 사용하십시오. pyexpat와 같은 구문 분석 전용 가제트가 필요하지 않거나 원하지 않는다면 ... ElementTree를 부분적으로 만 또는 다시 제대로 만들지 않게 될 것입니다.

    ElementTree 인터페이스를 구현 한 써드 파티 패키지 인 lxml도 있습니다.

    업데이트 누군가가 code-golf 게임을 시작했습니다. 여기에 당신이 요청한 데이터 구조를 만드는 내 항목이 있습니다 :

    # xs = """<encspot> etc etc </encspot"""
    >>> import xml.etree.cElementTree as et
    >>> from pprint import pprint as pp
    >>> pp([dict((attr.tag, attr.text) for attr in el) for el in et.fromstring(xs)])
    [{'Bitrate': '131',
      'Encoder': 'Gogo (after 3.0)',
      'Frame': 'no',
      'Frames': '6255',
      'Freq.': '44100',
      'Length': '00:02:43',
      'Mode': 'joint stereo',
      'Name': 'some filename.mp3',
      'Quality': 'good',
      'Size': '5,236,644'},
     {'Bitrate': '0', 'Name': 'foo.mp3'}]
    >>>
    

    변환 함수에 "속성"이름을 사전에 매핑하고자 할 수 있습니다.

    converters = {
        'Frames': int,
        'Size': lambda x: int(x.replace(',', '')),
        # etc
        }
    
  3. ==============================

    3.나는 또한 XML 문서와 파이썬 데이터 구조 사이에서 데이터를 변환하는 간단한 방법을 찾고있다. Golang의 XML 라이브러리와 비슷한 점은 데이터 구조에서 XML로 매핑하는 방법을 선언적으로 지정할 수있게 해준다.

    나는 또한 XML 문서와 파이썬 데이터 구조 사이에서 데이터를 변환하는 간단한 방법을 찾고있다. Golang의 XML 라이브러리와 비슷한 점은 데이터 구조에서 XML로 매핑하는 방법을 선언적으로 지정할 수있게 해준다.

    필자는 Python 용 라이브러리를 찾을 수 없었기 때문에 declarative XML 처리를 위해 declxml이라는 필자의 필요를 충족시키기 위해 필자에게 썼다.

    declxml을 사용하면 XML 문서의 구조를 선언적으로 정의하는 프로세서를 만들 수 있습니다. 프로세서는 파싱 및 직렬화는 물론 기본 수준의 유효성 검사를 수행하는 데 사용됩니다.

    이 XML 데이터를 declxml을 사용하여 사전 목록으로 파싱하는 것은 간단합니다.

    import declxml as xml
    
    xml_string = """
    <encspot>
      <file>
       <Name>some filename.mp3</Name>
       <Encoder>Gogo (after 3.0)</Encoder>
       <Bitrate>131</Bitrate>
      </file>
      <file>
       <Name>another filename.mp3</Name>
       <Encoder>iTunes</Encoder>
       <Bitrate>128</Bitrate>  
      </file>
    </encspot>
    """
    
    processor = xml.dictionary('encspot', [
        xml.array(xml.dictionary('file', [
            xml.string('Name'),
            xml.string('Encoder'),
            xml.integer('Bitrate')
        ]), alias='files')
    ])
    
    xml.parse_from_string(processor, xml_string)
    

    어느 것이 다음과 같은 결과를 낳는다.

    {'files': [
      {'Bitrate': 131, 'Encoder': 'Gogo (after 3.0)', 'Name': 'some filename.mp3'},
      {'Bitrate': 128, 'Encoder': 'iTunes', 'Name': 'another filename.mp3'}
    ]}
    

    사전 대신 데이터로 개체를 구문 분석하고 싶습니까? 너도 그렇게 할 수있어.

    import declxml as xml
    
    class AudioFile:
    
        def __init__(self):
            self.name = None
            self.encoder = None
            self.bit_rate = None
    
        def __repr__(self):
            return 'AudioFile(name={}, encoder={}, bit_rate={})'.format(
                self.name, self.encoder, self.bit_rate)
    
    
    processor = xml.array(xml.user_object('file', AudioFile, [
        xml.string('Name', alias='name'),
        xml.string('Encoder', alias='encoder'),
        xml.integer('Bitrate', alias='bit_rate')
    ]), nested='encspot')
    
    xml.parse_from_string(processor, xml_string)
    

    출력을 생성합니다.

    [AudioFile(name=some filename.mp3, encoder=Gogo (after 3.0), bit_rate=131),
     AudioFile(name=another filename.mp3, encoder=iTunes, bit_rate=128)]
    
  4. ==============================

    4.XML을 Object로 변환하는 정적 함수가 있다면이 함수는 다음과 같습니다.

    XML을 Object로 변환하는 정적 함수가 있다면이 함수는 다음과 같습니다.

    @classmethod   
    def from_xml(self,xml_str):
        #create XML Element
        root = ET.fromstring(xml_str)
        # create a dict from it
        d = {ch.tag: ch.text for ch in root.getchildren()}
        # return the object, created with **kwargs called from the Class, that's why its classmethod
        return self(**d)
    
  5. from https://stackoverflow.com/questions/5530857/parse-xml-file-into-python-object by cc-by-sa and MIT license