проблема: python xml добавляет элемент внутри цикла for

#python #xml

#python #xml

Вопрос:

спасибо, что нашли время для этого. у меня есть XML-файл с элементом под названием selectionset. идея состоит в том, чтобы взять этот элемент и изменить некоторые атрибуты и хвосты подэлементов, ту часть, которую я выполнил. для меня непонятно, почему, когда я пытаюсь добавить новые подэлементы к оригиналу (называемые наборами выбора), он только нажимает последний в списке inplist

     import xml.etree.ElementTree as etree
from xml.etree.ElementTree import *
from xml.etree.ElementTree import ElementTree
tree=ElementTree()
tree.parse('STRUCTURAL.xml')
root = tree.getroot()
col=tree.find('selectionsets/selectionset')
#find the value needed
val=tree.findtext('selectionsets/selectionset/findspec/conditions/condition/value/data')
setname=col.attrib['name']
listnames=val   " 6"
inplist=["D","E","F","G","H"]
entry=3
catcher=[]
ss=root.find('selectionsets')
outxml=ss
for i in range(len(inplist)):
    str(val)
    col.set('name',(setname  " "  inplist[i]))
    col.find('findspec/conditions/condition/value/data').text=str(inplist[i] val[1:3])
    #print (etree.tostring(col)) #everything working well til this point
    timper=col.find('selectionset')
    root[0].append(col)
    # new=etree.SubElement(outxml,timper)
#you need to create a tree with element tree before creating the xml file

itree=etree.ElementTree(outxml)
itree.write('Selection Sets.xml')
print (etree.tostring(outxml))

# print (Test_file.selectionset())


#Initial xml
<?xml version="1.0" encoding="UTF-8" ?>

<exchange xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://download.autodesk.com/us/navisworks/schemas/nw-exchange-12.0.xsd" units="ft" filename="STRUCTURAL.nwc" filepath="C:UsersRicardoDesktopComunTaller 3">
  <selectionsets>
    <selectionset name="Column Location" guid="565f5345-de06-4f5b-aa0f-1ae751c98ea8">
      <findspec mode="all" disjoint="0">
        <conditions>
          <condition test="contains" flags="10">
            <category>
              <name internal="LcRevitData_Element">Element</name>
            </category>
            <property>
              <name internal="lcldrevit_parameter_-1002563">Column Location Mark</name>
            </property>
            <value>
              <data type="wstring">C-A </data>
            </value>
          </condition>
        </conditions>
        <locator>/</locator>
      </findspec>
    </selectionset>
  </selectionsets>
</exchange>

#----Current Output
<selectionsets>
    <selectionset guid="565f5345-de06-4f5b-aa0f-1ae751c98ea8" name="Column Location H">
      <findspec disjoint="0" mode="all">
        <conditions>
          <condition flags="10" test="contains">
            <category>
              <name internal="LcRevitData_Element">Element</name>
            </category>
            <property>
              <name internal="lcldrevit_parameter_-1002563">Column Location Mark</name>
            </property>
            <value>
              <data type="wstring">H-A</data>
            </value>
          </condition>
        </conditions>
        <locator>/</locator>
      </findspec>
    </selectionset>
  <selectionset guid="565f5345-de06-4f5b-aa0f-1ae751c98ea8" name="Column Location H">
      <findspec disjoint="0" mode="all">
        <conditions>
          <condition flags="10" test="contains">
            <category>
              <name internal="LcRevitData_Element">Element</name>
            </category>
            <property>
              <name internal="lcldrevit_parameter_-1002563">Column Location Mark</name>
            </property>
            <value>
              <data type="wstring">H-A</data>
            </value>
          </condition>
        </conditions>
        <locator>/</locator>
      </findspec>
    </selectionset>
  <selectionset guid="565f5345-de06-4f5b-aa0f-1ae751c98ea8" name="Column Location H">
      <findspec disjoint="0" mode="all">
        <conditions>
          <condition flags="10" test="contains">
            <category>
              <name internal="LcRevitData_Element">Element</name>
            </category>
            <property>
              <name internal="lcldrevit_parameter_-1002563">Column Location Mark</name>
            </property>
            <value>
              <data type="wstring">H-A</data>
            </value>
          </condition>
        </conditions>
        <locator>/</locator>
      </findspec>
    </selectionset>
  <selectionset guid="565f5345-de06-4f5b-aa0f-1ae751c98ea8" name="Column Location H">
      <findspec disjoint="0" mode="all">
        <conditions>
          <condition flags="10" test="contains">
            <category>
              <name internal="LcRevitData_Element">Element</name>
            </category>
            <property>
              <name internal="lcldrevit_parameter_-1002563">Column Location Mark</name>
            </property>
            <value>
              <data type="wstring">H-A</data>
            </value>
          </condition>
        </conditions>
        <locator>/</locator>
      </findspec>
    </selectionset>
  <selectionset guid="565f5345-de06-4f5b-aa0f-1ae751c98ea8" name="Column Location H">
      <findspec disjoint="0" mode="all">
        <conditions>
          <condition flags="10" test="contains">
            <category>
              <name internal="LcRevitData_Element">Element</name>
            </category>
            <property>
              <name internal="lcldrevit_parameter_-1002563">Column Location Mark</name>
            </property>
            <value>
              <data type="wstring">H-A</data>
            </value>
          </condition>
        </conditions>
        <locator>/</locator>
      </findspec>
    </selectionset>
  <selectionset guid="565f5345-de06-4f5b-aa0f-1ae751c98ea8" name="Column Location H">
      <findspec disjoint="0" mode="all">
        <conditions>
          <condition flags="10" test="contains">
            <category>
              <name internal="LcRevitData_Element">Element</name>
            </category>
            <property>
              <name internal="lcldrevit_parameter_-1002563">Column Location Mark</name>
            </property>
            <value>
              <data type="wstring">H-A</data>
            </value>
          </condition>
        </conditions>
        <locator>/</locator>
      </findspec>
    </selectionset>
  </selectionsets>
  

Комментарии:

1. Предполагая, что вы используете xml.etree. ElementTree, метод find находит только первый элемент с указанным путем. Таким образом, вы находите один и тот же элемент на каждой итерации, модифицируете его, а затем добавляете его в корень. возможно, вам захочется выполнить итерацию по элементам и увеличить «inplist». Но это делает массу предположений. Было бы неплохо иметь возможность видеть исходный XML и полный код для обработки.

2. спасибо за ответ, это имеет смысл, но если я использую print внутри цикла, кажется, что он работает, я получаю желаемый результат, я новичок в обработке xml, поэтому я уверен, что допустил некоторые ошибки.

Ответ №1:

Вот что я смог собрать, и похоже, что он будет делать то, что вы ищете. Вот основные отличия: (1) Это будет выполнять итерацию по нескольким элементам selectionset (если в итоге у вас будет более одного), (2) Он создает глубокую копию элемента перед изменением значений (я думаю, вы всегда изменяли исходный «col»), (3) Он добавляетновый selectionset к тегу selectionsets, а не к корню.

Вот документация deepcopy

 import xml.etree.ElementTree as etree
import copy

tree=etree.ElementTree()
tree.parse('test.xml')
root = tree.getroot()
inplist=["D","E","F","G","H"]

for selectionset in tree.findall('selectionsets/selectionset'):
    for i in inplist:
        col = copy.deepcopy(selectionset)
        col.set('name', '%s %s' % (col.attrib['name'], i))
        data = col.find('findspec/conditions/condition/value/data')
        data.text = '%s%s' % (i, data.text[1:3])
        root.find('selectionsets').append(col)

itree = etree.ElementTree(root)
itree.write('Selection Sets.xml')
  

Комментарии:

1. Работает как чемпион!! спасибо, чувак, я изучаю ваш код прямо сейчас!

2. Рад слышать! @RicardoZepeda, если это то, что вы искали, и это работает, не могли бы вы принять это как ответ, чтобы я мог немного улучшить свою репутацию? Это позволит мне немного больше помочь на этом сайте.