2016-09-07 3 views
0

Я использую модуль запросов питона, чтобы получить XML из REST API TeamCity который выглядит следующим образом:Использование XML ElementTree для создания списка объектов с atrributes

<triggers count="10"> 
<trigger id="TRIGGER_1240" type="buildDependencyTrigger"> 
    <properties count="2"> 
     <property name="afterSuccessfulBuildOnly" value="true"/> 
     <property name="dependsOn" value="bt191"/> 
    </properties> 
</trigger> 
<trigger id="TRIGGER_1241" type="buildDependencyTrigger"> 
    <properties count="2"> 
     <property name="afterSuccessfulBuildOnly" value="true"/> 
     <property name="dependsOn" value="bt171"/> 
    </properties> 
</trigger> 
<trigger id="TRIGGER_1242" type="buildDependencyTrigger"> 
    <properties count="2"> 
     <property name="afterSuccessfulBuildOnly" value="true"/> 
     <property name="dependsOn" value="bt167"/> 
    </properties> 
</trigger> 
<trigger id="TRIGGER_1243" type="buildDependencyTrigger"> 
    <properties count="2"> 
     <property name="afterSuccessfulBuildOnly" value="true"/> 
     <property name="dependsOn" value="bt164"/> 
    </properties> 
</trigger> 
<trigger id="TRIGGER_1244" type="buildDependencyTrigger"> 
    <properties count="2"> 
     <property name="afterSuccessfulBuildOnly" value="true"/> 
     <property name="dependsOn" value="bt364"/> 
    </properties> 
</trigger> 
<trigger id="TRIGGER_736" type="buildDependencyTrigger"> 
    <properties count="2"> 
     <property name="afterSuccessfulBuildOnly" value="true"/> 
     <property name="dependsOn" value="Components_Ratchetdb"/> 
    </properties> 
</trigger> 
<trigger id="TRIGGER_149" type="buildDependencyTrigger"> 
    <properties count="2"> 
     <property name="afterSuccessfulBuildOnly" value="true"/> 
     <property name="dependsOn" value="Components_Filedb"/> 
    </properties> 
</trigger> 
<trigger id="TRIGGER_150" type="buildDependencyTrigger"> 
    <properties count="2"> 
     <property name="afterSuccessfulBuildOnly" value="true"/> 
     <property name="dependsOn" value="bt168"/> 
    </properties> 
</trigger> 
<trigger id="TRIGGER_1130" type="buildDependencyTrigger"> 
    <properties count="2"> 
     <property name="afterSuccessfulBuildOnly" value="true"/> 
     <property name="dependsOn" value="Components_Tbldb"/> 
    </properties> 
</trigger> 
<trigger id="vcsTrigger" type="vcsTrigger" inherited="true"> 
    <properties count="3"> 
     <property name="quietPeriod" value="60"/> 
     <property name="quietPeriodMode" value="USE_DEFAULT"/> 
     <property name="triggerRules" value="-:version.properties&#xA;-:comment=^Incremented:**&#xA;-:**/*-schema.sql"/> 
    </properties> 
</trigger> 

Я пытаюсь создать список объектов-триггеров с использованием класса. В идеале объект будет иметь идентификатор, тип и список атрибутов свойств как словари {name: value}. Мой код до сих пор:

class triggerList: 
    def __init__(self, triggerId, triggerType): 
     self.id = triggerId 
     self.type = triggerType 
     self.properties = [] 

    def add_property(self, buildProperty): 
     self.properties.append(buildProperty) 

def getAllTriggers(buildId): 
    url = path + 'buildTypes/id:' + buildId + '/triggers' 
    r = requests.get(url, auth=auth) 
    tree = ElementTree.fromstring(r.content) 
    listOfTriggers = [] 

    for trigger in tree.iter('trigger'): 
     triggerType = trigger.get('type') 
     triggerId = trigger.get('id') 
     triggerName = str(triggerId) 
     triggerName = triggerList(triggerId, triggerType) 
     listOfTriggers.append(triggerName) 

     for triggerProperty in tree.iter('property'): 
      propertyName = triggerProperty.get('name') 
      propertyValue = triggerProperty.get('value') 
      propDict = {propertyName : propertyValue} 
      triggerName.add_property(propDict) 

Это дает мне список объектов, но каждый объект имеет список каждого словаря свойств. Это результат:

a = listOfTriggers[1] 
print a.id, a.type, a.properties 

>>> TRIGGER_1241 buildDependencyTrigger [{'afterSuccessfulBuildOnly': 'true'}, {'dependsOn': 'bt191'}, {'afterSuccessfulBuildOnly': 'true'}, {'dependsOn': 'bt171'}, {'afterSuccessfulBuildOnly': 'true'}, {'dependsOn': 'bt167'}, {'afterSuccessfulBuildOnly': 'true'}, {'dependsOn': 'bt164'}, {'afterSuccessfulBuildOnly': 'true'}, {'dependsOn': 'bt364'}, {'afterSuccessfulBuildOnly': 'true'}, {'dependsOn': 'Components_Ratchetdb'}, {'afterSuccessfulBuildOnly': 'true'}, {'dependsOn': 'Components_Filedb'}, {'afterSuccessfulBuildOnly': 'true'}, {'dependsOn': 'bt168'}, {'afterSuccessfulBuildOnly': 'true'}, {'dependsOn': 'Components_Tbldb'}, {'quietPeriod': '60'}, {'quietPeriodMode': 'USE_DEFAULT'}, {'triggerRules': '-:version.properties\n-:comment=^Incremented:**\n-:**/*-schema.sql'}] 

Я не знаю, как остановить цикл только для свойств конкретного триггера. Есть ли способ использовать ElementTree для получения свойств только для определенного триггера? Есть ли более эффективный способ создания этого объекта?

ответ

0

Не прямо отвечая на вопрос, но вы можете быть изобретать колесо здесь, проверьте lxml.objectify package:

Основная идея заключается в том, чтобы скрыть использование XML позади обычных Python объектов, иногда называют данных- связывание. Он позволяет использовать XML-код , как если бы вы имели дело с нормальной иерархией объектов Python. Доступ к дочерним элементам XML-объекта развертывает атрибут объекта . Если есть несколько детей с тем же именем, можно использовать индексацию и . Типы данных Python автоматически извлекаются из содержимого XML и становятся доступными для обычных операторов Python.

+0

Спасибо, я не знал об этом! –

0

Простой синтаксис ошибка:

for triggerProperty in trigger.iter('property'): 
     propertyName = triggerProperty.get('name') 
     propertyValue = triggerProperty.get('value') 
     propDict = {propertyName : propertyValue} 
     triggerName.add_property(propDict) 

я итерация по всему дереву, а не триггеров. Должно быть:

для triggerProperty в триггером .iter («свойство»):

Смежные вопросы