重新计算 XML 个子元素

Recalculate XML child element

使用 python3 我正在尝试读取 xml 文件并根据项目中的属性重新计算值,然后用新值写入整个 xml 文件的副本。

xml 文件示例(完整文件约 10k 行):

<?xml version="1.0" encoding="utf-8"?>
<Items>
  <Item id="headscarf_d"
        name="{=wW3iouiU}Hijab"
        mesh="headscarf_d"
        culture="Culture.aserai"
        weight="0.5"
        value="63"
        appearance="1"
        Type="HeadArmor">
    <ItemComponent>
      <Armor head_armor="3"
             has_gender_variations="false"
             beard_cover_type="type3"
             hair_cover_type="all"
             modifier_group="cloth_unarmoured"
             material_type="Cloth"/>
    </ItemComponent>
    <Flags Civilian="true"
           UseTeamColor="true" />
  </Item>
  <Item id="open_head_scarf"
        name="{=qsVRoGUv}Open Head Scarf"
        mesh="aserai_helmet_c"
        culture="Culture.aserai"
        weight="0.6"
        value="174"
        appearance="1"
        Type="HeadArmor">
    <ItemComponent>
      <Armor head_armor="5"
             has_gender_variations="false"
             beard_cover_type="type3"
             hair_cover_type="all"
             modifier_group="cloth_unarmoured"
             material_type="Cloth"/>
    </ItemComponent>
    <Flags Civilian="true"
           UseTeamColor="true" />
  </Item>
  <Item id="woven_turban"
        name="{=ArPvuBYK}Woven Turban"
        subtype="head_armor"
        mesh="aserai_helmet_h"
        culture="Culture.aserai"
        weight="0.8"
        difficulty="0"
        value="250"
        appearance="1"
        Type="HeadArmor">
    <ItemComponent>
      <Armor head_armor="6"
             has_gender_variations="false"
             beard_cover_type="type2"
             hair_cover_type="all"
             modifier_group="cloth_unarmoured"
             material_type="Cloth"/>
    </ItemComponent>
    <Flags Civilian="true"
           UseTeamColor="true" />
  </Item>
</Items>

从示例中提取单个项目 xml,

<Item id="headscarf_d"
        name="{=wW3iouiU}Hijab"
        mesh="headscarf_d"
        culture="Culture.aserai"
        weight="0.5"
        value="63"
        appearance="1"
        Type="HeadArmor">
    <ItemComponent>
      <Armor head_armor="3"
             has_gender_variations="false"
             beard_cover_type="type3"
             hair_cover_type="all"
             modifier_group="cloth_unarmoured"
             material_type="Cloth"/>
    </ItemComponent>
    <Flags Civilian="true"
           UseTeamColor="true" />

为简单起见,假设我想取 Item 值(上面示例中的 63)除以 2 (63/2=31.5)。然后如果Item的ItemComponentmaterial_type="Cloth"再除以2(31.5/2=15.75)。最后舍入为整数,然后更新值并重复每个项目,然后写入新的更新 xml 文件。

我尝试使用 Reading, modifying and writing xml 但没有得到任何有用的东西。

您可能正在寻找以下内容:

from lxml import etree
import math

inv="""[your xml above]"""
doc = etree.XML(inv)

values = doc.xpath('//Item')
materials  = doc.xpath('Item//ItemComponent//Armor')
for t, m in zip(values,materials):
    if m.attrib['material_type'] == 'Cloth':
        val = float(t.attrib['value'])/4
        t.attrib['value'] = str(math.ceil(val))
    else:
        t.attrib['value']= str(math.ceil(val*2))
print(etree.tostring(doc).decode())

输出是 xml,根据需要将 Items/Item/@value 属性值除以 2 或 4,然后四舍五入 math.ceil()。由于您示例中的所有 Items 都将 cloth 作为属性 material_type 的值,因此它们都除以 4 并四舍五入为:

16
44
63