2016-09-07 75 views
0

我使用Python請求模塊從TeamCity的REST API,看起來像這樣獲得XML對象的列表:使用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> 

我試圖創建一個列表使用類的「觸發器」對象。理想情況下,對象將具有id,type和屬性屬性列表作爲{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

主要思想是躲在正常的Python 對象XML的使用,有時也被稱爲數據 - 捆綁。它允許您使用 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( '財產'):