簡體   English   中英

使用 ElementTree 從 XML 獲取值

[英]Get values form XML using ElementTree

我正在嘗試從這樣的 XML 文件中獲取值:

<?xml version="1.0"?>
<DeviceStorage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Objects>
    <Object Type="OBJECT_ANALOG_OUTPUT" Instance="5">
      <Properties>
        <Property Id="PROP_OBJECT_IDENTIFIER" Tag="BACNET_APPLICATION_TAG_OBJECT_ID">
          <Value>OBJECT_ANALOG_OUTPUT:5</Value>
        </Property>
        <Property Id="PROP_OBJECT_NAME" Tag="BACNET_APPLICATION_TAG_CHARACTER_STRING">
          <Value>B'JC2415'DUV'Y1</Value>
        </Property>
        <Property Id="PROP_OBJECT_TYPE" Tag="BACNET_APPLICATION_TAG_ENUMERATED">
          <Value>1</Value>
        </Property>
        <Property Id="3006" Tag="BACNET_APPLICATION_TAG_ENUMERATED">
          <Value>3</Value>
        </Property>
        <Property Id="PROP_DESCRIPTION" Tag="BACNET_APPLICATION_TAG_CHARACTER_STRING">
          <Value>Analog out Y1</Value>
        </Property>
        <Property Id="3001" Tag="BACNET_APPLICATION_TAG_OBJECT_ID">
          <Value>201:54</Value>
        </Property>
        <Property Id="PROP_PROFILE_NAME" Tag="BACNET_APPLICATION_TAG_CHARACTER_STRING">
          <Value>7-BA-PX-AO-SBCv10.02</Value>
        </Property>
        <Property Id="3121" Tag="BACNET_APPLICATION_TAG_CHARACTER_STRING">
          <Value>Building</Value>
          <Value>JET-C2.4-15</Value>
          <Value>DUV</Value>
          <Value>Analog out Y1</Value>
        </Property>
        <Property Id="3234" Tag="BACNET_APPLICATION_TAG_CHARACTER_STRING">
          <Value>B'JC2415'DUV'Y1</Value>
        </Property>
        <Property Id="PROP_PRESENT_VALUE" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>0</Value>
        </Property>
        <Property Id="PROP_STATUS_FLAGS" Tag="BACNET_APPLICATION_TAG_BIT_STRING">
          <Value>0000</Value>
        </Property>
        <Property Id="PROP_EVENT_STATE" Tag="BACNET_APPLICATION_TAG_ENUMERATED">
          <Value>0</Value>
        </Property>
        <Property Id="PROP_RELIABILITY" Tag="BACNET_APPLICATION_TAG_ENUMERATED">
          <Value>0</Value>
        </Property>
        <Property Id="PROP_OUT_OF_SERVICE" Tag="BACNET_APPLICATION_TAG_BOOLEAN">
          <Value>False</Value>
        </Property>
        <Property Id="PROP_UNITS" Tag="BACNET_APPLICATION_TAG_ENUMERATED">
          <Value>98</Value>
        </Property>
        <Property Id="PROP_RESOLUTION" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>0.1</Value>
        </Property>
        <Property Id="PROP_PRIORITY_ARRAY" Tag="BACNET_APPLICATION_TAG_NULL">
          <Value />
          <Value />
          <Value />
          <Value />
          <Value />
          <Value />
          <Value />
          <Value />
          <Value />
          <Value />
          <Value />
          <Value />
          <Value />
          <Value />
          <Value />
          <Value />
        </Property>
        <Property Id="PROP_RELINQUISH_DEFAULT" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>0</Value>
        </Property>
        <Property Id="PROP_COV_INCREMENT" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>0.1</Value>
        </Property>
        <Property Id="PROP_TIME_DELAY" Tag="BACNET_APPLICATION_TAG_UNSIGNED_INT">
          <Value>1</Value>
        </Property>
        <Property Id="PROP_NOTIFICATION_CLASS" Tag="BACNET_APPLICATION_TAG_UNSIGNED_INT">
          <Value>32</Value>
        </Property>
        <Property Id="PROP_HIGH_LIMIT" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>100</Value>
        </Property>
        <Property Id="PROP_LOW_LIMIT" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>0</Value>
        </Property>
        <Property Id="PROP_DEADBAND" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>0.5</Value>
        </Property>
        <Property Id="PROP_LIMIT_ENABLE" Tag="BACNET_APPLICATION_TAG_BIT_STRING">
          <Value>11</Value>
        </Property>
        <Property Id="PROP_EVENT_ENABLE" Tag="BACNET_APPLICATION_TAG_BIT_STRING">
          <Value>111</Value>
        </Property>
        <Property Id="PROP_ACKED_TRANSITIONS" Tag="BACNET_APPLICATION_TAG_BIT_STRING">
          <Value>111</Value>
        </Property>
        <Property Id="PROP_NOTIFY_TYPE" Tag="BACNET_APPLICATION_TAG_ENUMERATED">
          <Value>0</Value>
        </Property>
        <Property Id="PROP_EVENT_TIME_STAMPS" Tag="BACNET_APPLICATION_TAG_CONTEXT_SPECIFIC_DECODED">
          <Value>1/1/0001 12:00:00 AM;1/1/0001 12:00:00 AM</Value>
          <Value>1/1/0001 12:00:00 AM;1/1/0001 12:00:00 AM</Value>
          <Value>1/1/0001 12:00:00 AM;1/1/0001 12:00:00 AM</Value>
        </Property>
        <Property Id="PROP_DEVICE_TYPE" Tag="BACNET_APPLICATION_TAG_CHARACTER_STRING">
          <Value />
        </Property>
        <Property Id="3000" Tag="BACNET_APPLICATION_TAG_CHARACTER_STRING">
          <Value />
        </Property>
        <Property Id="3005" Tag="BACNET_APPLICATION_TAG_ENUMERATED">
          <Value>4</Value>
        </Property>
        <Property Id="3059" Tag="BACNET_APPLICATION_TAG_ENUMERATED">
          <Value>81</Value>
          <Value>6</Value>
          <Value>3</Value>
          <Value>3</Value>
          <Value>104</Value>
          <Value>4</Value>
          <Value>3</Value>
          <Value>3</Value>
          <Value>35</Value>
          <Value>10</Value>
          <Value>1</Value>
          <Value>1</Value>
          <Value>36</Value>
          <Value>5</Value>
          <Value>1</Value>
          <Value>0</Value>
          <Value>130</Value>
          <Value>5</Value>
          <Value>1</Value>
          <Value>0</Value>
          <Value>3011</Value>
          <Value>10</Value>
          <Value>3</Value>
          <Value>3</Value>
          <Value>45</Value>
          <Value>10</Value>
          <Value>5</Value>
          <Value>5</Value>
          <Value>59</Value>
          <Value>10</Value>
          <Value>5</Value>
          <Value>5</Value>
          <Value>25</Value>
          <Value>10</Value>
          <Value>1</Value>
          <Value>1</Value>
          <Value>113</Value>
          <Value>4</Value>
          <Value>3</Value>
          <Value>3</Value>
          <Value>3122</Value>
          <Value>10</Value>
          <Value>3</Value>
          <Value>3</Value>
          <Value>3114</Value>
          <Value>10</Value>
          <Value>3</Value>
          <Value>3</Value>
          <Value>17</Value>
          <Value>7</Value>
          <Value>3</Value>
          <Value>0</Value>
          <Value>72</Value>
          <Value>10</Value>
          <Value>5</Value>
          <Value>0</Value>
          <Value>3243</Value>
          <Value>7</Value>
          <Value>3</Value>
          <Value>0</Value>
          <Value>0</Value>
          <Value>5</Value>
          <Value>1</Value>
          <Value>0</Value>
          <Value>3014</Value>
          <Value>5</Value>
          <Value>3</Value>
          <Value>0</Value>
          <Value>3015</Value>
          <Value>5</Value>
          <Value>3</Value>
          <Value>0</Value>
          <Value>3019</Value>
          <Value>8</Value>
          <Value>5</Value>
          <Value>3</Value>
          <Value>3017</Value>
          <Value>4</Value>
          <Value>1</Value>
          <Value>1</Value>
          <Value>3018</Value>
          <Value>4</Value>
          <Value>1</Value>
          <Value>1</Value>
          <Value>3123</Value>
          <Value>4</Value>
          <Value>3</Value>
          <Value>3</Value>
          <Value>3124</Value>
          <Value>3</Value>
          <Value>5</Value>
          <Value>5</Value>
          <Value>3023</Value>
          <Value>8</Value>
          <Value>5</Value>
          <Value>3</Value>
          <Value>3054</Value>
          <Value>4</Value>
          <Value>1</Value>
          <Value>1</Value>
          <Value>3055</Value>
          <Value>4</Value>
          <Value>1</Value>
          <Value>1</Value>
          <Value>3126</Value>
          <Value>8</Value>
          <Value>5</Value>
          <Value>5</Value>
          <Value>3021</Value>
          <Value>8</Value>
          <Value>3</Value>
          <Value>3</Value>
          <Value>52</Value>
          <Value>10</Value>
          <Value>5</Value>
          <Value>5</Value>
          <Value>85</Value>
          <Value>2</Value>
          <Value>5</Value>
          <Value>5</Value>
          <Value>3211</Value>
          <Value>2</Value>
          <Value>5</Value>
          <Value>0</Value>
          <Value>3210</Value>
          <Value>5</Value>
          <Value>0</Value>
          <Value>0</Value>
          <Value>111</Value>
          <Value>5</Value>
          <Value>5</Value>
          <Value>0</Value>
          <Value>103</Value>
          <Value>5</Value>
          <Value>5</Value>
          <Value>1</Value>
          <Value>87</Value>
          <Value>5</Value>
          <Value>3</Value>
          <Value>0</Value>
          <Value>3236</Value>
          <Value>1</Value>
          <Value>3</Value>
          <Value>0</Value>
        </Property>
        <Property Id="3074" Tag="BACNET_APPLICATION_TAG_ENUMERATED">
          <Value>5</Value>
        </Property>
        <Property Id="3126" Tag="BACNET_APPLICATION_TAG_UNSIGNED_INT">
          <Value>0</Value>
        </Property>
        <Property Id="3008" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>0</Value>
        </Property>
        <Property Id="3009" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>100</Value>
        </Property>
        <Property Id="3114" Tag="BACNET_APPLICATION_TAG_UNSIGNED_INT">
          <Value>3</Value>
        </Property>
        <Property Id="3211" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>0</Value>
        </Property>
        <Property Id="3011" Tag="BACNET_APPLICATION_TAG_BOOLEAN">
          <Value>False</Value>
        </Property>
        <Property Id="3014" Tag="BACNET_APPLICATION_TAG_DATETIME">
          <Value>1/1/0001 12:00:00 AM</Value>
        </Property>
        <Property Id="3015" Tag="BACNET_APPLICATION_TAG_CHARACTER_STRING">
          <Value />
        </Property>
        <Property Id="3016" Tag="BACNET_APPLICATION_TAG_NULL" />
        <Property Id="3019" Tag="BACNET_APPLICATION_TAG_CHARACTER_STRING">
          <Value>T=1.1</Value>
        </Property>
        <Property Id="3017" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>100</Value>
        </Property>
        <Property Id="3018" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>0</Value>
        </Property>
        <Property Id="3021" Tag="BACNET_APPLICATION_TAG_ENUMERATED">
          <Value>2</Value>
        </Property>
        <Property Id="3023" Tag="BACNET_APPLICATION_TAG_CHARACTER_STRING">
          <Value />
        </Property>
        <Property Id="3054" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>0.01</Value>
        </Property>
        <Property Id="3055" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>0</Value>
        </Property>
        <Property Id="3210" Tag="BACNET_APPLICATION_TAG_BOOLEAN">
          <Value>False</Value>
        </Property>
        <Property Id="3123" Tag="BACNET_APPLICATION_TAG_UNSIGNED_INT">
          <Value>0</Value>
        </Property>
        <Property Id="3124" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>0</Value>
        </Property>
        <Property Id="3122" Tag="BACNET_APPLICATION_TAG_UNSIGNED_INT">
          <Value>2</Value>
        </Property>
        <Property Id="3212" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>0.1</Value>
        </Property>
        <Property Id="PROP_MAX_PRES_VALUE" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>100</Value>
        </Property>
        <Property Id="PROP_MIN_PRES_VALUE" Tag="BACNET_APPLICATION_TAG_REAL">
          <Value>0</Value>
        </Property>
        <Property Id="3236" Tag="BACNET_APPLICATION_TAG_BOOLEAN">
          <Value>False</Value>
        </Property>
        <Property Id="3243" Tag="BACNET_APPLICATION_TAG_BOOLEAN">
          <Value>False</Value>
        </Property>
      </Properties>
    </Object>
  </Objects>
</DeviceStorage>

它有多個<Object> </Object>對。 我的代碼可以獲取標簽但是不能獲取<Value></Value>里面的<Value></Value>

import xml.etree.ElementTree as ET
xmlfile = 'AS01.xml'

tree = ET.parse(xmlfile)
root = tree.getroot()

lst = tree.findall('Objects/Object/Properties')

for item in lst:
    for prop in item:
        obj_tag = prop.attrib['Tag']
        obj_value = prop.get('Value')
        print(obj_tag, obj_value)

對於每個<Object>我需要TypeInstance的值:

<Object Type="OBJECT_ANALOG_OUTPUT" Instance="5">

OBJECT_ANALOG_OUTPUT
5

以及基於 Property Id 的幾個值,例如:

<Property Id="PROP_OBJECT_NAME" Tag="BACNET_APPLICATION_TAG_CHARACTER_STRING"><Value>B'JC2415'DUV'Y1</Value>

PROP_OBJECT_NAME
B'JC2415'DUV'Y1

任何建議如何解決這個問題?

編輯:

這就是我解決問題的方法。 我不好,但對我有用:

import xml.etree.ElementTree as ET
xmlfile = 'AS01.xml'

tree = ET.parse(xmlfile)
root = tree.getroot()

PROP_OBJECT_IDENTIFIER = ''
PROP_OBJECT_NAME = ''
PROP_DESCRIPTION = ''
BACNET_APPLICATION_TAG_CHARACTER_STRING = ''

def format_string(obj_ident, obj_name,obj_desc,obj_addr):
    # Format the recovered values so I can pipe them into CSV files
    OBJECT_IDENTIFIER=''
    OBJECT_INSTANCE=''
    OBJECT_PATH=''
    OBJECT_NAME=''
    OBJECT_BUS=''
    OBJECT_ADDR=''
    
    str_colon = ':'
    str_apo = '\''
    str_eq = '='

    if str_colon in obj_ident:                      # Separate Identifier and instance number
        cnt = obj_ident.rfind(str_colon)
        cntp = cnt+1
        OBJECT_IDENTIFIER = obj_ident[0:cnt]
        OBJECT_INSTANCE = obj_ident[cntp:]
    if str_apo in obj_name:                         # Separate object path and name
        cnt = obj_name.rfind(str_apo)
        cntp = cnt+1
        OBJECT_PATH = obj_name[0:cnt]
        OBJECT_NAME = obj_name[cntp:]
    if str_eq in obj_addr:                          # Separate address type and the actual addres
        cnt = obj_addr.rfind(str_eq)
        cntp = cnt+1
        OBJECT_BUS = obj_addr[0:cnt]
        OBJECT_ADDR = obj_addr[cntp:]
    print(OBJECT_IDENTIFIER,',',OBJECT_INSTANCE,',',OBJECT_PATH,',',OBJECT_NAME,',',OBJECT_BUS,',',OBJECT_ADDR,',',obj_desc)
    

for obj in tree.findall('Objects/Object'):
    for prop in obj.findall('Properties/Property'):
        obj_id = prop.attrib['Id']
        obj_tag = prop.attrib['Tag']
        
        lst = prop.findall('Value')                 # Check for Value field
        lst_count = len(lst)                    
        if lst_count > 0:                           # If Value field exists
            obj_value = prop.find('Value').text
        elif lst_count == 0:                        # If Value field is missing
            obj_value = ''

        if obj_id == 'PROP_OBJECT_IDENTIFIER':      # Select only the necessary objects
            PROP_OBJECT_IDENTIFIER = obj_value
        if obj_id == 'PROP_OBJECT_NAME':
            PROP_OBJECT_NAME = obj_value
        if obj_id == 'PROP_DESCRIPTION':
            PROP_DESCRIPTION = obj_value
        if obj_id == '3019':
            BACNET_APPLICATION_TAG_CHARACTER_STRING = obj_value

    format_string(PROP_OBJECT_IDENTIFIER,PROP_OBJECT_NAME,PROP_DESCRIPTION,BACNET_APPLICATION_TAG_CHARACTER_STRING)
    PROP_OBJECT_IDENTIFIER = ''
    PROP_OBJECT_NAME = ''
    PROP_DESCRIPTION = ''
    BACNET_APPLICATION_TAG_CHARACTER_STRING = ''

輸出:

OBJECT_ANALOG_OUTPUT , 5 , B'JC2415'DUV , Y1 , T , 1.1 , Analog out Y1
OBJECT_ANALOG_OUTPUT , 6 , B'JC2415'DUV , Y2 , T , 1.2 , Analog out Y2
OBJECT_ANALOG_OUTPUT , 7 , B'JC2415'PVV , Y1 , T , 1.3 , Analog out Y1
OBJECT_ANALOG_OUTPUT , 8 , B'JC2415'PVV , Y2 , T , 1.4 , Analog out Y2

不確定我是否正確回答了這個問題,但對於我想要的值:

values = [i.text for i in tree.findall('.//*/Value')]

對於“對象”屬性:

types=[i.get('Type') for i in tree.findall('.//*Object/[@Type]')]
instances=[i.get('Instance') for i in a.findall('.//*Object/[@Instance]')]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM