2010-11-23 3 views
1

에 LXML합니다 : http://www.xml.com/pub/a/2005/01/19/amara.html전환은이 같은 LXML 라이브러리 뭔가 달성하기 위해 노력하고 파이썬

from amara import binderytools 

container = binderytools.bind_file('labels.xml') 
for l in container.labels.label: 
    print l.name, 'of', l.address.city 

하지만 내 느낌이 젖지 가장 어려운 시간을 보냈습니다! 내가하고 싶은 것은 'X'라는 이름의 루트 노드로 내려간 다음 'Y'라는 이름의 두 번째 자식으로 내린 다음 'Z'라는 이름의 모든 자식을 가져온 다음 그 자식 만 특성을 갖는 것보다 오래 보관합니다. 'name'을 'bacon'으로 설정 한 다음 나머지 각 노드에 대해 'W'라는 하위 노드를 모두 살펴보고 A, B 및 C라는 유일한 W 하위를 보는 일부 필터를 기반으로 하위 집합 만 유지합니다. 다음과 같이 (최적화되지 않은) 의사 코드로 처리해야합니다.

result = [] 
X = root(doc(parse(xml_file_name))) 
Y = X[1] # Second child 
Zs = Y.children() 
for Z in Zs: 
    if Z.name != 'bacon': continue # skip 
    Ws = Z.children() 
    record = [] 
    assert(len(Ws) == 9) 
    W0 = Ws[0] 
    assert(W0.A == '42') 
    record.append(str(W0.A) + " " + W0.B + " " + W0.C)) 
    ... 
    W1 = Ws[1] 
    assert(W1.A == '256') 
    ... 
    result.append(record) 

이것은 내가 수행하려고하는 것과 같습니다. 이 코드를 더 깔끔하게 만들려고 노력하기 전에이 코드를 작동 시키려고합니다.

이 API에서 분실되어 도움을 주시기 바랍니다. 질문이 있으면 알려주세요. 난 단지 당신이 유지하고자하는 어떤 기록 같은데요하지만

답변

3
import lxml.etree as le 
import io 

content='''\ 
<foo><X><Y>skip this</Y><Y><Z name="apple"><W>not here</W></Z> 
<Z name="bacon"><W><A>42</A><B>b</B><C>c</C></W><W><A>256</A><B>b</B><C>c</C></W></Z> 
<Z name="bacon"><W><A>42</A><B>b</B><C>c</C></W><W><A>256</A><B>b</B><C>c</C></W></Z> 
</Y></X></foo> 
''' 
doc=le.parse(io.BytesIO(content)) 
# print(le.tostring(doc, pretty_print=True)) 
result=[] 
Zs=doc.xpath('//X/Y[2]/Z[@name="bacon"]') 
for Z in Zs: 
    Ws=Z.xpath('W') 
    record=[] 
    assert(len(Ws)==2) #<--- Change to 9   
    abc=Ws[0].xpath('descendant::text()') 
    # print(abc) 
    # ['42', 'b', 'c'] 
    assert(abc[0] == '42') 
    record.append(' '.join(abc)) 
    abc=Ws[1].xpath('descendant::text()')  
    assert(abc[0] == '256') 
    result.append(record) 
print(result) 
# [['42 b c'], ['42 b c']] 

이, 조 업 할 수있는 내부 루프를 방법이 될 수 있습니다

for Z in Zs: 
    Ws=Z.xpath('W') 
    assert(len(Ws)==2) #<--- Change to 9 
    a_vals=('42','256') 
    for W,a_val in zip(Ws,a_vals): 
     abc=W.xpath('descendant::text()') 
     assert(abc[0] == a_val) 
     result.append([' '.join(abc)]) 
print(result) 
# [['42 b c'], ['256 b c'], ['42 b c'], ['256 b c']] 
+0

하나는 내가 깨달았을 때 대답을 쓰기 시작 내 코드가 너의 것과 거의 90 % 유사하게 보였고, 다른 10 %에서는 네가 더 좋아 보였다. – snapshoe

+0

감사합니다. –

+0

후속 질문을하고 싶습니다. ' abc ...'와 같은 것을 보면, 어떻게'column.id'와'column.name'을 볼 수 있습니까? 이미 한 예를 보았습니다.'Zs = doc.xpath ('// X/Y [2]/Z [@ name = "bacon"]')'하지만, 필요한 것은 개별 속성을 볼 수있는 능력입니다. 나는 이미 "선택한"노드입니다. –

관련 문제