元素树分析

2024-10-01 09:42:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我对元素树是完全陌生的,我一直在尝试更改xml文件中的一些文本。我已经阅读了一些示例,但似乎找不到与我要编辑的xml结构相同的示例。你知道吗

我尝试访问的特定元素是许多AvClass元素中的一个,如下所示。。你知道吗

<AvClass id="MMpr">
  <AvProp id="ASET" name="name" type="string">Untitled</AvProp>
  <AvProp id="ASET" name="kind" type="string">Interplay Folder</AvProp>
  <AvProp id="ASET" name="attributes" type="int16">17</AvProp>
  <AvProp id="ASET" name="type" type="int16">32</AvProp>
  <AvProp id="ASET" name="attrList" type="reference">
    <AvClass id="ATTR">
      <AvProp id="ATTR" name="__OMFI:ATTR:NumItems" type="int32">3</AvProp>
      <List id="OMFI:ATTR:AttrRefs">
        <ListElem>
          <AvProp id="ATTR" name="OMFI:ATTB:Kind" type="int32">2</AvProp>
          <AvProp id="ATTR" name="OMFI:ATTB:Name" type="string">ATS_MM_PROJECT_DIRECTORY_NAME</AvProp>
          <AvProp id="ATTR" name="OMFI:ATTB:StringAttribute" type="string">Projects//Post//Grading</AvProp>
        </ListElem>
        <ListElem>
          <AvProp id="ATTR" name="OMFI:ATTB:Kind" type="int32">1</AvProp>
          <AvProp id="ATTR" name="OMFI:ATTB:Name" type="string">ATS_MM_APPEND_PROJECT</AvProp>
          <AvProp id="ATTR" name="OMFI:ATTB:IntAttribute" type="int32">1</AvProp>
        </ListElem>
        <ListElem>
          <AvProp id="ATTR" name="OMFI:ATTB:Kind" type="int32">1</AvProp>
          <AvProp id="ATTR" name="OMFI:ATTB:Name" type="string">ATS_MM_VERIFY_DIRECTORY</AvProp>
          <AvProp id="ATTR" name="OMFI:ATTB:IntAttribute" type="int32">0</AvProp>
        </ListElem>
        <ListElem/>
      </List>
    </AvClass>
  </AvProp>
</AvClass>

id="MMpr" is unique and contains a ListElem - ATS_MM_PROJECT_DIRECTORY_NAME - which has a string 'Projects//Post//Grading'.

编辑:抱歉,我忘记发布代码示例:

我想把这个字符串改成'Projects//NEW//string//ETC'之类的东西,我正在努力尝试。有人能给我指出正确的方向吗?你知道吗

自动取款机。我使用了很多for循环和比较运算符,但我确信有一种优雅的方法可以做到这一点。你知道吗

tree = ET.parse(this_file) # create tree from file
root = tree.getroot() # set the root     
for x in root.iter('AvClass'): # iterates thru ALL classes    
        for prop in x: # get 1st level properties of class

            # Interplay Paths
            for chi1 in prop: # child of prop
                for chi2 in chi1: # child of child
                    if 'ATS_MM_PROJECT_DIRECTORY_NAME' in str(chi2.text):
                        print(chi2.text)
                        #chi2.text = 'Projects//NEW//STRING//ETC'

我想更改列表中的下一个AvProp elements文本值(可能为空)


Tags: nameidforstringtypeattrmmint32
1条回答
网友
1楼 · 发布于 2024-10-01 09:42:10

你是个老家伙。你知道吗

因为您知道目标字符串,所以可以使用它来标识AvProp元素。在这段代码中,我验证是否可以看到文本,然后将新文本分配给元素。最后,我将显示xml的完整新版本。你知道吗

>>> from lxml import etree
>>> tree = etree.parse('this_file.xml')
>>> avprop = tree.xpath('.//AvProp[text()="ATS_MM_PROJECT_DIRECTORY_NAME"]')[0]
>>> avprop.text
'ATS_MM_PROJECT_DIRECTORY_NAME'
>>> avprop.text = 'SOMETHING REALLY NOTICEABLE'
>>> etree.tostring(tree)
b'<AvClass id="MMpr">\n  <AvProp id="ASET" name="name" type="string">Untitled</AvProp>\n  <AvProp id="ASET" name="kind" type="string">Interplay Folder</AvProp>\n  <AvProp id="ASET" name="attributes" type="int16">17</AvProp>\n  <AvProp id="ASET" name="type" type="int16">32</AvProp>\n  <AvProp id="ASET" name="attrList" type="reference">\n    <AvClass id="ATTR">\n      <AvProp id="ATTR" name="__OMFI:ATTR:NumItems" type="int32">3</AvProp>\n      <List id="OMFI:ATTR:AttrRefs">\n        <ListElem>\n          <AvProp id="ATTR" name="OMFI:ATTB:Kind" type="int32">2</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:Name" type="string">SOMETHING REALLY NOTICEABLE</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:StringAttribute" type="string">Projects//Post//Grading</AvProp>\n        </ListElem>\n        <ListElem>\n          <AvProp id="ATTR" name="OMFI:ATTB:Kind" type="int32">1</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:Name" type="string">ATS_MM_APPEND_PROJECT</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:IntAttribute" type="int32">1</AvProp>\n        </ListElem>\n        <ListElem>\n          <AvProp id="ATTR" name="OMFI:ATTB:Kind" type="int32">1</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:Name" type="string">ATS_MM_VERIFY_DIRECTORY</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:IntAttribute" type="int32">0</AvProp>\n        </ListElem>\n        <ListElem/>\n      </List>\n    </AvClass>\n  </AvProp>\n</AvClass>'

编辑:尽管输入文件显示同级在特定的顺序中彼此跟随,但在处理xml时不能假定顺序。换句话说,同级可以按任何顺序传递给程序。你知道吗

如果这次我没听错的话,这似乎可以胜任。你知道吗

这次,在识别了已知元素之后,我得到了它的父元素,然后在它的子元素中寻找一个具有所需的name属性的元素。如果没有一个子级满足这个要求,那么elements将是一个空列表。否则,只有列表中的第一项内容将更改。你知道吗

>>> from lxml import etree
>>> tree = etree.parse('this_file.xml')
>>> elements = tree.xpath('.//AvProp[text()="ATS_MM_PROJECT_DIRECTORY_NAME"]/../*[@name="OMFI:ATTB:StringAttribute"]')
>>> elements[0].text
'Projects//Post//Grading'
>>> if elements:
...     elements[0].text = '*** SOMETING I CAN SEE EASILY ***'
...     
>>> etree.tostring(tree)
b'<AvClass id="MMpr">\n  <AvProp id="ASET" name="name" type="string">Untitled</AvProp>\n  <AvProp id="ASET" name="kind" type="string">Interplay Folder</AvProp>\n  <AvProp id="ASET" name="attributes" type="int16">17</AvProp>\n  <AvProp id="ASET" name="type" type="int16">32</AvProp>\n  <AvProp id="ASET" name="attrList" type="reference">\n    <AvClass id="ATTR">\n      <AvProp id="ATTR" name="__OMFI:ATTR:NumItems" type="int32">3</AvProp>\n      <List id="OMFI:ATTR:AttrRefs">\n        <ListElem>\n          <AvProp id="ATTR" name="OMFI:ATTB:Kind" type="int32">2</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:Name" type="string">ATS_MM_PROJECT_DIRECTORY_NAME</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:StringAttribute" type="string">*** SOMETING I CAN SEE EASILY ***</AvProp>\n        </ListElem>\n        <ListElem>\n          <AvProp id="ATTR" name="OMFI:ATTB:Kind" type="int32">1</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:Name" type="string">ATS_MM_APPEND_PROJECT</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:IntAttribute" type="int32">1</AvProp>\n        </ListElem>\n        <ListElem>\n          <AvProp id="ATTR" name="OMFI:ATTB:Kind" type="int32">1</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:Name" type="string">ATS_MM_VERIFY_DIRECTORY</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:IntAttribute" type="int32">0</AvProp>\n        </ListElem>\n        <ListElem/>\n      </List>\n    </AvClass>\n  </AvProp>\n</AvClass>'

然后,为了验证代码是否能够处理缺少该元素的xml文件,我“注释掉”了该元素并重新执行了代码。这一次执行elements[0].text(在生产代码中不会执行的操作)的尝试失败了,正如预期的那样,xml保持不变。你知道吗

>>> tree = etree.parse('this_file.xml')
>>> elements = tree.xpath('.//AvProp[text()="ATS_MM_PROJECT_DIRECTORY_NAME"]/../*[@name="OMFI:ATTB:StringAttribute"]')
>>> elements[0].text
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
IndexError: list index out of range
>>> if elements:
...     elements[0].text = '*** SOMETING I CAN SEE EASILY ***'
... 
>>> etree.tostring(tree)
b'<AvClass id="MMpr">\n  <AvProp id="ASET" name="name" type="string">Untitled</AvProp>\n  <AvProp id="ASET" name="kind" type="string">Interplay Folder</AvProp>\n  <AvProp id="ASET" name="attributes" type="int16">17</AvProp>\n  <AvProp id="ASET" name="type" type="int16">32</AvProp>\n  <AvProp id="ASET" name="attrList" type="reference">\n    <AvClass id="ATTR">\n      <AvProp id="ATTR" name="__OMFI:ATTR:NumItems" type="int32">3</AvProp>\n      <List id="OMFI:ATTR:AttrRefs">\n        <ListElem>\n          <AvProp id="ATTR" name="OMFI:ATTB:Kind" type="int32">2</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:Name" type="string">ATS_MM_PROJECT_DIRECTORY_NAME</AvProp>\n          <!  AvProp id="ATTR" name="OMFI:ATTB:StringAttribute" type="string">Projects//Post//Grading</AvProp  >\n        </ListElem>\n        <ListElem>\n          <AvProp id="ATTR" name="OMFI:ATTB:Kind" type="int32">1</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:Name" type="string">ATS_MM_APPEND_PROJECT</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:IntAttribute" type="int32">1</AvProp>\n        </ListElem>\n        <ListElem>\n          <AvProp id="ATTR" name="OMFI:ATTB:Kind" type="int32">1</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:Name" type="string">ATS_MM_VERIFY_DIRECTORY</AvProp>\n          <AvProp id="ATTR" name="OMFI:ATTB:IntAttribute" type="int32">0</AvProp>\n        </ListElem>\n        <ListElem/>\n      </List>\n    </AvClass>\n  </AvProp>\n</AvClass>'

相关问题 更多 >