2011-03-22 36 views
12

Bir xml dosyasında belirli bir etiket olup olmadığını kontrol etmem gerekiyor. ŞuPython Lxml (objectify): Bir etiketin var olup olmadığını kontrol etme

<main> 
     <elem1/> 
     <elem2>Hi</elem2> 
     <elem3/> 
     ... 
</main> 

böyle, ben, hata kontrolü ile çirkin bir hack kullanıyorum:

Örneğin, ben etiketi, bu snippet'indeki varsa görmek istiyorum da

try: 
    if root.elem1.tag: 
     foo = elem1 
except AttributeError: 
    foo = "error finding elem1" 

Ben Düğüm bulamıyorsa dizeyi özelleştirmek (yani "-tagname-bulunamıyor").

Uzun bir değişkenler listesi kontrol etmeliyim ve kodu 100 kez tekrarlamak istemiyorum.

herhangi bir öneriniz? böylece, içeriğini almak için eğer,

<main> 
<asset name="Virtual Dvaered Unpresence"> 
    <virtual/> 
    <presence> 
    <faction>Dvaered</faction> 
    <value>-1000.000000</value> 
    <range>0</range> 
    </presence> 
</asset> 
<asset name="Virtual Empire Small"> 
    <virtual/> 
    <presence> 
    <faction>Empire</faction> 
    <value>100.000000</value> 
    <range>2</range> 
    </presence> 
</asset> 
</main> 

Ben etiketi var olup olmadığını kontrol etmek istiyorum ve:

Düzenleme: İşte

fiili xml dosyasının bir kelepir olduğunu.

Düzeltme: Tamam, iki yanıtı birleştireceğim, ancak yalnızca bir tanesine oy verebiliyorum. Afedersiniz.

Düzenleme 3: Burada XPath hakkında İlgili soru: Python lxml (objectify): Xpath troubles

cevap

5

Eğer elem2 olmalıdır değerini almak istiyorum varsayalım, bunu bulmak için xpath kullanabilirsiniz. Bunun için

tree = etree.parse(StringIO(htmlString), etree.HTMLParser()).getroot() 
youWantValue = tree.xpath('/main/elem2')[0].text 
+0

Düğüm varsa, ne olur? Bir hata ya da sadece boş bir değer veriyor? – Biosci3c

+0

@ Biosci3c belirli bir örnek bir hata verir '[0]' 'xpath' çağrısı tarafından döndürülen ilk değeri denemeyi denemek.İstemeden çıkarılmadan önce listenin boş olup olmadığını kontrol ettiyseniz, bir hata olmadan bir testiniz olacaktır. btw, bu verilenler arasında en iyi uygulama yanıtı olarak görüyorum –

+0

Tamam, ben XPATH önerisini beğendim, bu yüzden bunu da kullanacağım BTW, bence sonunda bir kapanış parantezini kaçırıyorsun. satır – Biosci3c

1

Belgeniz nispeten kısa Etiketlere değişken adları sizin set eşleşen arayan <main> tüm çocukları adımlayabilirsiniz olma eğilimindedir ise:

tree = lxml.etree.fromstring(DATA) 
NAMES = set(['elem1', 'elem3']) 
for node in tree.iterchildren(): 
    if node.tag in NAMES: 
     print 'found', node.tag 

Yoksa bir anda her değişken adı bir arayabilirsiniz:

for tag in ('elem1', 'elem3'): 
    if tree.find(tag) is not None: 
     print 'found', tag 
+0

ile çalışıyorum belge oldukça uzun. Soruya bir parça koyacağım. – Biosci3c

+0

Ayrıca, aramak için sınırları oluşturan ilk satırı mı? – Biosci3c

6

Edit: örnek dosya için güncellenmiş yanıt.

Her bir varlığı belirli etiketlerde aramak istediğinizi varsayıyorum. Eğer öyleyse, benim için çalıştı aşağıdaki:

import lxml.objectify 

# Parse the file. 
tree = lxml.objectify.parse('sample.xml') 
root = tree.getroot() 

# Which elements to find. 
to_find = set(['presence/faction', 'presence/value', 'fake']) 

# Go through each asset in the document. 
for asset in root.findall('asset'): 
    # Check for each element. 
    for name in to_find: 
     node = asset.find(name) 
     if node is not None: 
      print 'Found %s, its value is %s' % (name, node) 
     else: 
      print 'Unable to find %s' % name 

çıkışı oldu:

Found presence/value, its value is -1000.0 
Found presence/faction, its value is Dvaered 
Unable to find fake 
Found presence/value, its value is 100.0 
Found presence/faction, its value is Empire 
Unable to find fake 
+0

Bu, harika çalışacak gibi görünüyor. Şansı kazandığımda deneyeceğim. Sadece açıklığa kavuşturmak için set() 'i argüman olarak bir listeyle mi kullanıyorsunuz? – Biosci3c

+0

Evet. Yapıcı, başlangıç ​​girişlerini sette vermek için tekrarlanabilir bir süreç alır. Ayrıntılar için [docs] 'a (http://docs.python.org/library/stdtypes.html#set) bakın. – Blair

+0

Tamam, bir sorun. Bu atama değerlerini belirli değişkenlere nasıl yapabilirim (örneğin, var_fac = varlık/hizme, var_değer = varlık/değer? – Biosci3c

23

hasattr() çalışır:

if hasattr(root, 'elem1'): 
    foo = root.elem1 
+2

Bu, sevdiğim cevap. Hala çirkin, ama bu Python'un hatası, posterin değil. Sadece çocuk varlığını kontrol etmek istiyorum, tam güçlü bir xpath işlemcisini çalıştırmam. – odigity

+1

Dahili hasattr'ın getattr'ı arayarak ve istisnaları yakalayarak işe yaradığını unutmayın, bu yüzden dışarıda olduğu kadar çirkin bir şekilde (en azından son kontrol ettiğimde) :) –

İlgili konular