get value from variable which contains xml - python

I have the next jenkins API script:
import jenkins
import json
import re
server = jenkins.Jenkins('https://jenkins_url', username, password)
nodes = json.dumps(server.get_nodes())
nodes = re.sub('\"offline\"|[:{} \[\]]|true,|false,|\"name\"|\"','',nodes).split(',')
for label in nodes:
if label != 'master':
print label
node_config = server.get_node_config(label)
print node_config
node_config contains for example the next xml text:
<?xml version="1.0" encoding="UTF-8"?>
<slave>
<name>test.server</name>
<description></description>
<remoteFS>/var/lib/jenkins</remoteFS>
<numExecutors>1</numExecutors>
<mode>EXCLUSIVE</mode>
<retentionStrategy class="hudson.slaves.RetentionStrategy$Always"/>
<launcher class="hudson.plugins.sshslaves.SSHLauncher" plugin="ssh-slaves#1.10">
<host>test.server</host>
<port>7777</port>
<credentialsId>d0970a8f-d124</credentialsId>
<maxNumRetries>0</maxNumRetries>
<retryWaitTime>0</retryWaitTime>
</launcher>
<label>BuildServer</label>
<nodeProperties/>
<userId>test</userId>
</slave>
I want to get value of each of tag to obtain on output eg test.server etc.
Could you please help me with it?

xml_text = """<?xml version="1.0" encoding="UTF-8"?>
<slave>
<name>test.server</name>
<description></description>
<remoteFS>/var/lib/jenkins</remoteFS>
<numExecutors>1</numExecutors>
<mode>EXCLUSIVE</mode>
<retentionStrategy class="hudson.slaves.RetentionStrategy$Always"/>
<launcher class="hudson.plugins.sshslaves.SSHLauncher" plugin="ssh-slaves#1.10">
<host>test.server</host>
<port>7777</port>
<credentialsId>d0970a8f-d124</credentialsId>
<maxNumRetries>0</maxNumRetries>
<retryWaitTime>0</retryWaitTime>
</launcher>
<label>BuildServer</label>
<nodeProperties/>
<userId>test</userId>
</slave>
"""
import xml.etree.ElementTree
root = xml.etree.ElementTree.fromstring(xml_text)
# show only a particular tag
for name in root.findall('name'):
print(name.text)
# show all children at first level
for child in root:
print('%s: %s' % (child.tag, child.text))
# build a dict (will only get last of any duplicate tags, and no children)
slave = {child.tag: child.text for child in root}
# build a dict (will only get last of any duplicate tags)
def xml_todict(xml_node):
dict_ = {}
for child in xml_node:
dict_[child.tag] = xml_todict(child)
dict_.update(xml_node.attrib)
if not dict_:
return xml_node.text
if xml_node.text and 'text' not in dict_:
dict_['text'] = xml_node.text
return dict_
slave = xml_todict(root)

Related

Python ElementTree adding a child

I have an xml file which looks like this:
<keyboard>
</keyboard>
I want to make it look like this:
<keyboard>
<keybind key="W-c-a"><action name="Execute"><command>sudo shutdown now</command></action></keybind>
</keyboard>
I have a function to add this which has parameters that will change the key and the command. Is this possible to do? If yes, how can I do this?
(The function):
def add_keybinding(self, keys, whatToExec):
keybinding = "<keybind key=\"%s\"><action name=\"Execute\"><command>%s</command><action></keybind>" % (keys, whatToExec)
f = open("/etc/xdg/openbox/rc.xml", "a")
try:
# I want to append the keybinding variable to the <keyboard>
except IOError as e:
print(e)
From the doc, you can try the following:
def add_keybinding(keys, whatToExec, filename):
keybind = ET.Element('keybind')
keybind.set("key", keys)
action = ET.SubElement(keybind, 'action')
action.set("name", "Execute")
command = ET.SubElement(action, 'command')
command.text = whatToExec
tree = ET.parse(filename)
tree.getroot().append(keybind)
tree.write(filename)
Explanation:
Create the keybind tag using xml.etree.ElementTree.Element : keybind = ET.Element('keybind')
Set a property using set: keybind.set("key", keys)
Create the action tag as a sub element of keybind using
xml.etree.ElementTree.SubElement: action = ET.SubElement(keybind, 'action')
Set the property as at step 2: action.set("name", "Execute")
Create command tag: action.set("name", "Execute")
Set command tag content using .text: command.text = whatToExec
Read file using xml.etree.ElementTree.parse: tree = ET.parse(filename)
Append keybind tag to the doc root element using append*
Export new xml to file using write
Full example:
import xml.etree.ElementTree as ET
from xml.dom import minidom
def add_keybinding(keys, whatToExec, filename):
keybind = ET.Element('keybind')
keybind.set("key", keys)
action = ET.SubElement(keybind, 'action')
action.set("name", "Execute")
command = ET.SubElement(action, 'command')
command.text = whatToExec
tree = ET.parse(filename)
tree.getroot().append(keybind)
tree.write(filename)
return tree
def prettify(elem):
rough_string = ET.tostring(elem, 'utf-8')
return minidom.parseString(rough_string).toprettyxml(indent=" ")
filename = "test.xml"
for i in range(3):
tree = add_keybinding(str(i), "whatToExec " + str(i), filename)
print(prettify(tree.getroot()))
Output:
<?xml version="1.0" ?>
<keyboard>
<keybind key="0">
<action name="Execute">
<command>whatToExec 0</command>
</action>
</keybind>
<keybind key="1">
<action name="Execute">
<command>whatToExec 1</command>
</action>
</keybind>
<keybind key="2">
<action name="Execute">
<command>whatToExec 2</command>
</action>
</keybind>
</keyboard>

How to add new nodes into XML tree, reading from a list in Python?

I am trying to read from a list and add the values as new nodes into an XML in Python
list = ['163','164','165']
and after appending list values into the node trackingnumbers,
The xml should looks like this :
<?xml version="1.0" encoding="UTF-8"?>
<trackingrequest>
<user>TAIL</user>
<password>20</password>
<trackingnumbers>
<trackingnumber>163</trackingnumber>
<trackingnumber>164</trackingnumber>
<trackingnumber>165</trackingnumber>
</trackingnumbers>
</trackingrequest>
I have got it this far but i am stuck at creating dynamic variables inside a loop, which creates new nodes inside trackingnumbers
def GenerateXML():
root = ET.Element("trackingrequest")
m1 = ET.Element("user")
root.append(m1)
m1.text = 'TAIL'
m2 = ET.Element("password")
root.append(m2)
m2.text = '20'
m3 = ET.Element("trackingnumbers")
root.append(m3)
d = {}
for i in range(list):
d["trackingid_{0}".format(i)] = ET.SubElement(m3, "trackingnumber")
d['trackingid_1'].text = i*2
tree = ET.ElementTree(root)
The idea is to find trackingnumbers and add the required sub elements
import xml.etree.ElementTree as ET
lst = ['163', '164', '165']
xml = '''<?xml version="1.0" encoding="UTF-8"?>
<trackingrequest>
<user>TAIL</user>
<password>20</password>
<trackingnumbers>
</trackingnumbers>
</trackingrequest>'''
root = ET.fromstring(xml)
tracking_numbers = root.find('.//trackingnumbers')
for num in lst:
tn = ET.SubElement(tracking_numbers, 'trackingnumber')
tn.text = num
ET.dump(root)
output
<?xml version="1.0" encoding="UTF-8"?>
<trackingrequest>
<user>TAIL</user>
<password>20</password>
<trackingnumbers>
<trackingnumber>163</trackingnumber>
<trackingnumber>164</trackingnumber>
<trackingnumber>165</trackingnumber>
</trackingnumbers>
</trackingrequest>

How to get the content of specific grandchild from xml file through python

Hi I am very new to python programming. I have an xml file of structure:
<?xml version="1.0" encoding="UTF-8"?>
-<LidcReadMessage xsi:schemaLocation="http://www.nih.gov http://troll.rad.med.umich.edu/lidc/LidcReadMessage.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.nih.gov" uid="1.3.6.1.4.1.14519.5.2.1.6279.6001.1307390687803.0">
-<ResponseHeader>
<Version>1.8.1</Version>
<MessageId>-421198203</MessageId>
<DateRequest>2007-11-01</DateRequest>
<TimeRequest>12:30:44</TimeRequest>
<RequestingSite>removed</RequestingSite>
<ServicingSite>removed</ServicingSite>
<TaskDescription>Second unblinded read</TaskDescription>
<CtImageFile>removed</CtImageFile>
<SeriesInstanceUid>1.3.6.1.4.1.14519.5.2.1.6279.6001.179049373636438705059720603192</SeriesInstanceUid>
<DateService>2008-08-18</DateService>
<TimeService>02:05:51</TimeService>
<ResponseDescription>1 - Reading complete</ResponseDescription>
<StudyInstanceUID>1.3.6.1.4.1.14519.5.2.1.6279.6001.298806137288633453246975630178</StudyInstanceUID>
</ResponseHeader>
-<readingSession>
<annotationVersion>3.12</annotationVersion>
<servicingRadiologistID>540461523</servicingRadiologistID>
-<unblindedReadNodule>
<noduleID>Nodule 001</noduleID>
-<characteristics>
<subtlety>5</subtlety>
<internalStructure>1</internalStructure>
<calcification>6</calcification>
<sphericity>3</sphericity>
<margin>3</margin>
<lobulation>3</lobulation>
<spiculation>4</spiculation>
<texture>5</texture>
<malignancy>5</malignancy>
</characteristics>
-<roi>
<imageZposition>-125.000000 </imageZposition>
<imageSOP_UID>1.3.6.1.4.1.14519.5.2.1.6279.6001.110383487652933113465768208719</imageSOP_UID>
......
There are four which contains multiple . Each contains an . I need to extract the information in from all of these headers.
Right now I am doing this:
import xml.etree.ElementTree as ET
tree = ET.parse('069.xml')
root = tree.getroot()
#lst = []
for readingsession in root.iter('readingSession'):
for roi in readingsession.findall('roi'):
id = roi.findtext('imageSOP_UID')
print(id)
but it ouputs like this:
Process finished with exit code 0.
If anyone can help.
The real problem as been wit the namespace. I tried with and without it, but it didn't work with this code.
ds = pydicom.dcmread("000071.dcm")
uid = ds.SOPInstanceUID
tree = ET.parse("069.xml")
root = tree.getroot()
for child in root:
print(child.tag)
if child.tag == '{http://www.nih.gov}readingSession':
read = child.find('{http://www.nih.gov}unblindedReadNodule')
if read != None:
nodule_id = read.find('{http://www.nih.gov}noduleID').text
xml_uid = read.find('{http://www.nih.gov}roi').find('{http://www.nih.gov}imageSOP_UID').text
if xml_uid == uid:
print(xml_uid, "=", uid)
roi= read.find('{http://www.nih.gov}roi')
print(roi)
This work completely fine to get a uid from dicom image of LIDC/IDRI dataset and then extract the same uid from xml file for it region of interest.

How can I parse a XML file to a dictionary in Python?

I 'am trying to parse a XML file using the Python library minidom (even tried xml.etree.ElementTree API).
My XML (resource.xml)
<?xml version='1.0'?>
<quota_result xmlns="https://some_url">
</quota_rule>
<quota_rule name='max_mem_per_user/5'>
<users>user1</users>
<limit resource='mem' limit='1550' value='921'/>
</quota_rule>
<quota_rule name='max_mem_per_user/6'>
<users>user2 /users>
<limit resource='mem' limit='2150' value='3'/>
</quota_rule>
</quota_result>
I would like to parse this file and store inside a dictionnary the information in the following form and be able to access it:
dict={user1=[resource,limit,value],user2=[resource,limit,value]}
So far I have only been able to do things like:
docXML = minidom.parse("resource.xml")
for node in docXML.getElementsByTagName('limit'):
print node.getAttribute('value')
You can use getElementsByTagName and getAttribute to trace the result:
dict_users = dict()
docXML = parse('mydata.xml')
users= docXML.getElementsByTagName("quota_rule")
for node in users:
user = 'None'
tag_user = node.getElementsByTagName("users") #check the length of the tag_user to see if tag <users> is exist or not
if len(tag_user) ==0:
print "tag <users> is not exist"
else:
user = tag_user[0]
resource = node.getElementsByTagName("limit")[0].getAttribute("resource")
limit = node.getElementsByTagName("limit")[0].getAttribute("limit")
value = node.getElementsByTagName("limit")[0].getAttribute("value")
dict_users[user.firstChild.data]=[resource, limit, value]
if user == 'None':
dict_users['None']=[resource, limit, value]
else:
dict_users[user.firstChild.data]=[resource, limit, value]
print(dict_users) # remove the <users>user1</users> in xml
Output:
tag <users> is not exist
{'None': [u'mem', u'1550', u'921'], u'user2': [u'mem', u'2150', u'3']}

Parsing complex Xml Python 3.4

I have the following xml :
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Suite>
<TestCase>
<TestCaseID>001</TestCaseID>
<TestCaseDescription>Hello</TestCaseDescription>
<TestSetup>
<Action>
<ActionCommand>gfdg</ActionCommand>
<TimeOut>dfgd</TimeOut>
<BamSymbol>gff</BamSymbol>
<Side>vfbgc</Side>
<PrimeBroker>fgfd</PrimeBroker>
<Size>fbcgc</Size>
<PMCode>fdgd</PMCode>
<Strategy>fdgf</Strategy>
<SubStrategy>fgf</SubStrategy>
<ActionLogEndPoint>fdgf</ActionLogEndPoint>
<IsActionResultLogged>fdgf</IsActionResultLogged>
<ValidationStep>
<IsValidated>fgdf</IsValidated>
<ValidationFormat>dfgf</ValidationFormat>
<ResponseEndpoint>gdf</ResponseEndpoint>
<ResponseParameterName>fdgfdg</ResponseParameterName>
<ResponseParameterValue>gff</ResponseParameterValue>
<ExpectedValue>fdgf</ExpectedValue>
<IsValidationResultLogged>gdfgf</IsValidationResultLogged>
<ValidationLogEndpoint>fdgf</ValidationLogEndpoint>
</ValidationStep>
</Action>
<Action>
<ActionCommand>New Order</ActionCommand>
<TimeOut>fdgf</TimeOut>
<BamSymbol>fdg</BamSymbol>
<Side>C(COVER)</Side>
<PrimeBroker>CSPB</PrimeBroker>
<Size>fdgd</Size>
<PMCode>GREE</PMCode>
<Strategy>Generalist</Strategy>
<SubStrategy>USLC</SubStrategy>
<ActionLogEndPoint>gfbhgf</ActionLogEndPoint>
<IsActionResultLogged>fdgf</IsActionResultLogged>
<ValidationStep>
<IsValidated>fdgd</IsValidated>
<ValidationFormat>dfgfd</ValidationFormat>
<ResponseEndpoint>dfgf</ResponseEndpoint>
<ResponseParameterName>fdgfd</ResponseParameterName>
<ResponseParameterValue>dfgf</ResponseParameterValue>
<ExpectedValue>fdg</ExpectedValue>
<IsValidationResultLogged>fdgdf</IsValidationResultLogged>
<ValidationLogEndpoint>fdgfd</ValidationLogEndpoint>
</ValidationStep>
</Action>
</TestCase>
</Suite>
Based on the ActionCommand i am getting either one block , the issue is could not get the sub parent tag (ValidationStep) and all its child tags . Can anyone help?
My code:
for testSetup4 in root.findall(".TestCase/TestSetup/Action"):
if testSetup4.find('ActionCommand').text == "gfdg":
for c1 in testSetup4:
t2.append(c1.tag)
v2.append(c1.text)
for k,v in zip(t2, v2):
test_case[k] = v
I am not able to get ValidationStep (sub parent) and its corresponding tags.
Simply add another loop to iterate through the <ValidationStep> node and its children. Also, you do not need the two other lists as you can update a dictionary during the parsing loop:
import xml.etree.ElementTree as et
dom = et.parse('Input.xml')
root = dom.getroot()
test_case = {}
for testSetup4 in root.findall(".TestCase/TestSetup/Action"):
if testSetup4.find('ActionCommand').text == "gfdg":
for c1 in testSetup4:
test_case[c1.tag]= c1.text
for vd in testSetup4.findall("./ValidationStep/*"):
test_case[vd.tag]= vd.text
Alternatively, use the double slash operator to search for all children including grandchildren of <Action> element:
for testSetup4 in root.findall(".TestCase/TestSetup/Action"):
if testSetup4.find('ActionCommand').text == "gfdg":
for c1 in testSetup4.findall(".//*"):
test_case[c1.tag]= c1.text

Categories