2008-09-17 71 views
12

Tôi cần có danh sách các giá trị thuộc tính từ các phần tử con trong Python.Lấy danh sách các giá trị thuộc tính XML trong Python

Cách dễ nhất để giải thích bằng ví dụ.

Với một số XML như thế này:

<elements> 
    <parent name="CategoryA"> 
     <child value="a1"/> 
     <child value="a2"/> 
     <child value="a3"/> 
    </parent> 
    <parent name="CategoryB"> 
     <child value="b1"/> 
     <child value="b2"/> 
     <child value="b3"/> 
    </parent> 
</elements> 

Tôi muốn để có thể làm điều gì đó như:

>>> getValues("CategoryA") 
['a1', 'a2', 'a3'] 
>>> getValues("CategoryB") 
['b1', 'b2', 'b3'] 

Nó trông giống như một công việc cho XPath nhưng tôi là mở cửa cho tất cả khuyến nghị. Tôi cũng muốn nghe về các thư viện Python XML yêu thích của bạn.

Trả lời

7

Tôi không thực sự là một tay cũ ở Python, nhưng đây là giải pháp XPath sử dụng libxml2.

import libxml2 

DOC = """<elements> 
    <parent name="CategoryA"> 
     <child value="a1"/> 
     <child value="a2"/> 
     <child value="a3"/> 
    </parent> 
    <parent name="CategoryB"> 
     <child value="b1"/> 
     <child value="b2"/> 
     <child value="b3"/> 
    </parent> 
</elements>""" 

doc = libxml2.parseDoc(DOC) 

def getValues(cat): 
    return [attr.content for attr in doc.xpathEval("/elements/parent[@name='%s']/child/@value" % (cat))] 

print getValues("CategoryA") 

Với kết quả ...

['a1', 'a2', 'a3'] 
+0

Được chấp nhận vì đây là những gì tôi đã kết thúc sử dụng. Đó là một lớp lót đơn giản và tôi không cần cài đặt thêm bất kỳ mô-đun nào. Kiểm tra các câu trả lời khác quá - có một số công cụ tốt ở đó. – roomaroo

+0

python test.py Traceback (gần đây nhất gọi cuối cùng): File "test.py", dòng 1, trong nhập khẩu libxml2 ImportError: Không có mô-đun tên libxml2 –

+0

@SR truy vấn: Có thể bạn sẽ cần phải sử dụng libxml2 ví dụ libxml2 này. –

2

Tôi phải thừa nhận mình là người hâm mộ của xmltramp do tính dễ sử dụng của nó.

Truy cập trên trở thành:

import xmltramp 

    values = xmltramp.parse('''...''') 

    def getValues(values, category): 
    cat = [ parent for parent in values['parent':] if parent(name) == category ] 
    cat_values = [ child(value) for child in parent['child':] for parent in cat ] 
    return cat_values 

    getValues(values, "CategoryA") 
    getValues(values, "CategoryB") 
2

Bạn có thể làm điều này với BeautifulSoup

>>> from BeautifulSoup import BeautifulStoneSoup 
>>> soup = BeautifulStoneSoup(xml) 
>>> def getValues(name): 
. . .  return [child['value'] for child in soup.find('parent', attrs={'name': name}).findAll('child')] 

Nếu bạn đang làm việc với HTML/XML tôi sẽ khuyên bạn hãy nhìn vào BeautifulSoup. Nó tương tự như cây DOM nhưng chứa nhiều chức năng hơn.

3

Sử dụng một W3 DOM tiêu chuẩn như minidom của stdlib, hoặc pxdom:

def getValues(category): 
    for parent in document.getElementsByTagName('parent'): 
     if parent.getAttribute('name')==category: 
      return [ 
       el.getAttribute('value') 
       for el in parent.getElementsByTagName('child') 
      ] 
    raise ValueError('parent not found') 
6

ElementTree 1.3 (tiếc là không 1.2 đó là một bao gồm với Python) supports XPath như thế này:

import elementtree.ElementTree as xml 

def getValues(tree, category): 
    parent = tree.find(".//parent[@name='%s']" % category) 
    return [child.get('value') for child in parent] 

Sau đó, bạn có thể làm

>>> tree = xml.parse('data.xml') 
>>> getValues(tree, 'CategoryA') 
['a1', 'a2', 'a3'] 
>>> getValues(tree, 'CategoryB') 
['b1', 'b2', 'b3'] 

lxml.etree (mà cũng cung cấp giao diện ElementTree) cũng sẽ làm việc trong cùng một cách.

2

Thư viện python xml ưa thích của tôi là lxml, bao gồm libxml2.
XPath không dường như con đường để đi đây, vì vậy tôi muốn viết những dòng này như một cái gì đó như:

from lxml import etree 

def getValues(xml, category): 
    return [x.attrib['value'] for x in 
      xml.findall('/parent[@name="%s"]/*' % category)] 

xml = etree.parse(open('filename.xml')) 

>>> print getValues(xml, 'CategoryA') 
['a1', 'a2', 'a3'] 
>>> print getValues(xml, 'CategoryB') 
['b1', 'b2', 'b3] 
0

Trong Python 3.x, lấy một danh sách các thuộc tính là một nhiệm vụ đơn giản của việc sử dụng các thành viên items()

Sử dụng ElementTree, đoạn mã bên dưới hiển thị một cách để nhận danh sách các thuộc tính. LƯU Ý rằng ví dụ này không xem xét các không gian tên, nếu có, sẽ cần được tính toán.

import xml.etree.ElementTree as ET 

    flName = 'test.xml' 
    tree = ET.parse(flName) 
    root = tree.getroot() 
    for element in root.findall('<child-node-of-root>'): 
     attrList = element.items() 
     print(len(attrList), " : [", attrList, "]") 

THAM KHẢO:

Element.items()
Returns the element attributes as a sequence of (name, value) pairs.
The attributes are returned in an arbitrary order.

Python manual

Các vấn đề liên quan