WSMAN XML feldolgozás

0 votes
asked Apr 13, 2016 in IRF tantárgy by kivancsifancsi (39 points)  

Sziasztok!

Problémám akadt a wsman által generált XML feldolgozásával. Alapvetően az a baj, hogy namespacek vannak az xml-ben, emiatt az xml.etree.ElementTree-vel nem tudom kiszedni a nekem szükséges értékeket. Az Element.findall() függvény nincs felkészítve a namespace-kre.

Valahol olvastam, hogy az számít szép megoldásnak, ha a wsman által kiadott XML-t ténylegesen XML-ként dolgozzuk fel, és úgy keresünk benne, de a namespace-k nagyon megnehezítik a feldolgozást. Nincs valami módszer arra, hogy ezeket kiszűrjem?

Köszönöm előre is!

1 Answer

+1 vote
answered Apr 13, 2016 by nadudvarit (1,121 points)  
selected Apr 13, 2016 by kovari
 
Best answer

Sajnos, ahogy azt tapasztalhattad ElementTree nem a legokosabb, ha névterekről van szó.

A képességei kimerülnek abban, hogy a különböző keresési metódusoknak átadj egy dict-et, amiben egy kulcs egy prefix az érték pedig a hozzátartozó uri:

import xml.etree.ElementTree as ET

namespaces = {"s": "http://www.w3.org/2003/05/soap-envelope"}
root = ET.fromstring(xml_source)
print(root.findall("s:Body", namespaces))

Persze ez csak annyit könnyít az életeden, hogy {http://www.w3.org/2003/05/soap-envelope}Body helyett s:Body-ra kereshetsz.

Találtam egy drasztikusabb megoldást is a névterek teljes eltávolítására (itt).
Ez valóban eltávolít minden névteret az XML fájlból, viszont ennek a használatát előbb mindenképp gondold át! Nem véletlenül vannak azok a névterek a fájlban, lehet hogy így ütközni fognak a tagek, vagy egyéb információt veszíthetsz.

from io import StringIO
import xml.etree.ElementTree as ET

# instead of ET.fromstring(xml_str)
it = ET.iterparse(StringIO(xml_str))
for _, el in it:
    if '}' in el.tag:
        el.tag = el.tag.split('}', 1)[1]  # strip all namespaces
root = it.root
print(root.findall("Body"))
commented Apr 13, 2016 by kivancsifancsi (39 points)  
Köszönöm! Alapvetően az a baj, hogy nincs más lehetőség a wsman használatkor, csak az XML feldolgozása.  A feladatom meg kiköti, hogy olyan Python3 scriptet kell írnom, ami WS-Management-et használ...  Pedig mennyivel jobb lenne a Python-lmiwbem modul...  :(
commented Apr 13, 2016 by kovari (2,221 points)  
edited Apr 13, 2016 by kovari
Mindenki nem kaphat lmiwbemes feladatot :) de hidd el, nekik a funkcionalitás komplexebb is, mert megússzák ezt a wsmanos xml gányolást.

Amúgy a 2. módszer is nyugodtan használható, amit Tomi írt.
commented Apr 15, 2016 by gyeresicsaba (33 points)  
edited Apr 15, 2016 by gyeresicsaba
Olyat lehet csinálni valahogyan, hogy a scriptből a subprocess.check_output-ba belerakom a grepet valahogy? Ha csak simán így csinálom, akkor nem jó :  subprocess.check_output(["wsman", "-h", input['Host'][0], "-u", input['User'][0], "-p", input['Password'][0], "enumerate", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_DiskPartition", "|", "grep", "keresendő szöveg"],universal_newlines=True)
Szerk: Meglett, ha valakit érdekelne:
http://stackoverflow.com/questions/13332268/python-subprocess-command-with-pipe
commented Apr 15, 2016 by nadudvarit (1,121 points)  
Először is ez simán mehetett volna külön kérdésnek is.
Másodszor: ha greppeled a kimenetet akkor ugye nem XML-ként akarod már feldolgozni az adatokat, amit azért meggondolnék. Persze mivel nem látom a szkriptedet, egy szóval sem állítom, hogy a te megoldásod nem lesz jó, csak ahogy említve lett az XML-es feldolgozást jobban preferáljuk.
...