python - 하기 - 어떻게 파이썬에서 XML을 파싱합니까?




파이썬 xml 읽기 (10)

xml.etree.ElementTree 대 lxml

이 두 라이브러리는 내가 사용하기에 가장 유용하다고 생각하는 라이브러리 중 일부입니다.

xml.etree.ElementTree :

  1. 표준 라이브러리에서 : 모듈을 설치할 필요가 없습니다.

1xml

  1. 쉽게 XML 선언 작성 : 예 : standalone = "no"를 추가해야합니까?
  2. 멋진 인쇄 : 여분의 코드없이 멋진 들여 쓰기 된 XML을 만들 수 있습니다.
  3. Objectify 기능 : 일반 Python 객체 계층 구조를 다루는 것처럼 XML을 사용할 수 있습니다 .a

xml을 포함하는 데이터베이스에 많은 행이 있고 그 행을 거치며 특정 노드 속성의 인스턴스가 몇 개인 지 표시하는 Python 스크립트를 작성하려고합니다. 예를 들어, 내 나무는 다음과 같습니다.

<foo>
   <bar>
      <type foobar="1"/>
      <type foobar="2"/>
   </bar>
</foo>

파이썬을 사용하여 XML의 속성 1과 2에 어떻게 액세스 할 수 있습니까?


XML

<foo>
   <bar>
      <type foobar="1"/>
      <type foobar="2"/>
   </bar>
</foo>

PYTHON_CODE

import xml.etree.cElementTree as ET

tree = ET.parse("foo.xml")
root = tree.getroot() 
root_tag = root.tag
print(root_tag) 

for form in root.findall("./bar/type"):
    x=(form.attrib)
    z=list(x)
    for i in z:
        print(x[i])

산출:

foo
1
2

나는 ElementTree 제안한다. 동일한 API에 대한 다른 호환 가능한 구현 (예 : lxml 및 Python 표준 라이브러리 자체의 cElementTree )이 있습니다. 이러한 맥락에서, 그들이 주로 추가하는 것은 더 빠른 속도입니다. 프로그래밍 부분의 용이성은 ElementTree 정의한 API에 달려 있습니다.

XML로부터 Element 인스턴스 e 를 생성 한 후 (예 : XML 함수로), 또는 파일을 파싱하여

import xml.etree.ElementTree
e = xml.etree.ElementTree.parse('thefile.xml').getroot()

또는 ElementTree 표시된 다른 많은 방법 중 하나를 사용하면 다음과 같이 할 수 있습니다.

for atype in e.findall('type'):
    print(atype.get('foobar'))

비슷한, 일반적으로 꽤 단순한 코드 패턴.


나는 Python xml.domxml.dom.minidom 아주 쉽게 찾는다 . DOM은 많은 양의 XML에는 적합하지 않지만 입력이 상당히 적 으면 잘 작동합니다.


또 다른 가능성을 추가하기 위해 간단한 xml-to-python-object 라이브러리이기 때문에 untangle 을 사용할 수 있습니다. 여기에 예제가 있습니다.

설치

pip install untangle

용법

귀하의 XML 파일 (조금 변경) :

<foo>
   <bar name="bar_name">
      <type foobar="1"/>
   </bar>
</foo>

untangle로 속성에 액세스하기 :

import untangle

obj = untangle.parse('/path_to_xml_file/file.xml')

print obj.foo.bar['name']
print obj.foo.bar.type['foobar']

출력은 다음과 같습니다.

bar_name
1

엉킴에 대한 자세한 내용은 here .
또한 (궁금하신 분은) here XML과 Python으로 작업하기위한 도구 목록을 찾을 수 here (가장 일반적인 것들이 이전 답변에서 언급 된 것을 볼 수 있습니다).


여기 cElementTree 사용하여 매우 간단하지만 효과적인 코드.

try:
    import cElementTree as ET
except ImportError:
  try:
    # Python 2.5 need to import a different module
    import xml.etree.cElementTree as ET
  except ImportError:
    exit_err("Failed to import cElementTree from any known place")      

def find_in_tree(tree, node):
    found = tree.find(node)
    if found == None:
        print "No %s in file" % node
        found = []
    return found  

# Parse a xml file (specify the path)
def_file = "xml_file_name.xml"
try:
    dom = ET.parse(open(def_file, "r"))
    root = dom.getroot()
except:
    exit_err("Unable to open and parse input definition file: " + def_file)

# Parse to find the child nodes list of node 'myNode'
fwdefs = find_in_tree(root,"myNode")

출처:

http://www.snip2code.com/Snippet/991/python-xml-parse?fromPage=1


declxml 제안 할 수도 있습니다.

전체 공개 : ElementTree를 사용하여 수십 줄의 명령형 / 직렬화 코드를 작성할 필요없이 XML과 Python 데이터 구조간에 변환하는 방법을 찾고 있었기 때문에이 라이브러리를 작성했습니다.

declxml을 사용하면 프로세서 를 사용하여 XML 문서의 구조를 선언적으로 정의하고 XML과 Python 데이터 구조를 매핑하는 방법을 사용합니다. 프로세서는 기본 수준의 유효성 검사는 물론 직렬화 및 구문 분석에 모두 사용됩니다.

파이썬 데이터 구조를 파싱하는 것은 간단합니다.

import declxml as xml

xml_string = """
<foo>
   <bar>
      <type foobar="1"/>
      <type foobar="2"/>
   </bar>
</foo>
"""

processor = xml.dictionary('foo', [
    xml.dictionary('bar', [
        xml.array(xml.integer('type', attribute='foobar'))
    ])
])

xml.parse_from_string(processor, xml_string)

어떤 출력을 생산 :

{'bar': {'foobar': [1, 2]}}

동일한 프로세서를 사용하여 데이터를 XML로 직렬화 할 수도 있습니다.

data = {'bar': {
    'foobar': [7, 3, 21, 16, 11]
}}

xml.serialize_to_string(processor, data, indent='    ')

다음 출력을 생성합니다.

<?xml version="1.0" ?>
<foo>
    <bar>
        <type foobar="7"/>
        <type foobar="3"/>
        <type foobar="21"/>
        <type foobar="16"/>
        <type foobar="11"/>
    </bar>
</foo>

사전 대신 개체를 사용하여 작업하려면 개체를 서로주고받는 프로세서를 정의 할 수 있습니다.

import declxml as xml

class Bar:

    def __init__(self):
        self.foobars = []

    def __repr__(self):
        return 'Bar(foobars={})'.format(self.foobars)


xml_string = """
<foo>
   <bar>
      <type foobar="1"/>
      <type foobar="2"/>
   </bar>
</foo>
"""

processor = xml.dictionary('foo', [
    xml.user_object('bar', Bar, [
        xml.array(xml.integer('type', attribute='foobar'), alias='foobars')
    ])
])

xml.parse_from_string(processor, xml_string)

다음 출력을 생성합니다.

{'bar': Bar(foobars=[1, 2])}

lxml.objectify 는 정말 간단합니다.

샘플 텍스트 가져 오기 :

from lxml import objectify
from collections import defaultdict

count = defaultdict(int)

root = objectify.fromstring(text)

for item in root.bar.type:
    count[item.attrib.get("foobar")] += 1

print dict(count)

산출:

{'1': 1, '2': 1}

minidom 은 가장 빠르고 똑바로 전진합니다 :

XML :

<data>
    <items>
        <item name="item1"></item>
        <item name="item2"></item>
        <item name="item3"></item>
        <item name="item4"></item>
    </items>
</data>

PYTHON :

from xml.dom import minidom
xmldoc = minidom.parse('items.xml')
itemlist = xmldoc.getElementsByTagName('item')
print(len(itemlist))
print(itemlist[0].attributes['name'].value)
for s in itemlist:
    print(s.attributes['name'].value)

산출

4
item1
item1
item2
item3
item4

import xml.etree.ElementTree as ET
data = '''<foo>
           <bar>
               <type foobar="1"/>
               <type foobar="2"/>
          </bar>
       </foo>'''
tree = ET.fromstring(data)
lst = tree.findall('bar/type')
for item in lst:
    print item.get('foobar')

이것은 foobar 속성의 값을 출력합니다.





xml