【问题标题】:Getting the last tag in ElementTree and append text获取 ElementTree 中的最后一个标签并附加文本
【发布时间】:2018-06-18 17:04:35
【问题描述】:

我有一些具有以下结构的 XML:

       <root>
           <parent-1>
              <text>blah-1</text>
              <properties>
                 <property type="R" id="0005">text-value-A</property>
                 <property type="W" id="0003">text-value-B</property>
                 <property type="H" id="0002">text-value-C</property>
                 <property type="W" id="0008">text-value-D</property>
              </properties>
           </parent-1>
           <parent-2>
              <text>blah-2</text>
              <properties>
                 <property type="W" id="0004">text-value-A</property>
                 <property type="H" id="0087">text-value-B</property>
              </properties>
           </parent-2>
           <parent-3>
              <text>blah-3</text>
              <properties>
                 <property type="H" id="0087">text-value-C</property>
                 <property type="R" id="0008">text-value-A</property>
              </properties>
           </parent-3>
           <parent-4>
              <text>blah-4</text>
              <properties>
                 <property type="H" id="0019">text-value-C</property>
                 <property type="R" id="0060">text-value-A</property>
              </properties>
           </parent-4>
       </root>

目前,我正在解析 text-value-s 并将它们与一些字符串 ! 连接起来,但是对于在 properties 级别中最后出现的 text-value-X,我需要分配一些其他字符串&amp;,并输出如下内容: text-value-A!text-value-B!text-value-C!text-value-D&amp;text-value-A!text-value-B&amp;text-value-C!text-value-A.

由于&lt;property 中的属性不能特定于标签/具有随机值,因此if(item.text == 'text-value-A') #get text-value-A of parent-3 之类的内容将不起作用。

---------

我没有保留重复的text-value-s(在这种情况下不需要parent-4,因为text-value-s 和parent-3 是相同的)并且我想保留顺序,所以我正在使用enumerate以下:

alist = []
for item in root.findall('parent/properties/property'):
   alist.append(item.text)
self.alist = '!'.join([a for b,a in enumerate(alist) if a not in alist[:b]]

鉴于上述所需的输出,我想知道我是否需要一种不同的方法来解决这个问题,或者类似以下的概念会以某种方式起作用:

alist = []
for item in root.findall('parent/properties/property'):
   alist.append(item.text)
   for element in alist:
      if element in alist[-1]:
         self.alist = '&'.join([a for b,a in enumerate(alist) if a not in alist[:b]]
      if not element in alist[-1]:
         self.alist = '!'.join([a for b,a in enumerate(alist) if a not in alist[:b]]

谢谢

【问题讨论】:

  • 一个固有的问题是 xml 子节点是 not 有序的。在您的示例中,我看到 property 元素按 id 属性排序。这个可以用吗?
  • 好点,但这应该是随机的,抱歉 - 现在已编辑。
  • 至少我还不清楚。也许您可以向我们展示该输入的输出结果。
  • 顺便说一句,要在 SO(例如我)上亲自回复某人,请键入“at”字符以接收可能收件人的菜单。
  • @BillBell 给定上面的 XML,输出应该是这个字符串:text-value-A!text-value-B!text-value-C!text-value-D&amp;text-value-A!text-value-B&amp;text-value-C!text-value-A

标签: python xml-parsing elementtree xml.etree


【解决方案1】:

这可能是你想要的。

  • xpath 公式“.//properties”生成一个包含四个元素的列表。
  • property_texts 将包含每个文本的列表。
  • any 谓词用于测试当前属性的文本集是否曾见过。如果不是,则将这些文本作为列表添加到集合中。 (重要的是使用set 逻辑以避免丢失不同顺序的重复集。)

from xml.etree import ElementTree

tree = ElementTree.parse('bt123.xml')
property_text_lists = []
for properties in tree.findall('.//properties'):
    property_texts = [p.text for p in properties]
    if any([set(property_texts)==set(ptl) for ptl in property_text_lists]):
        break
    property_text_lists.append(property_texts)

print ('&'.join(['!'.join(property_text_lists[i]) for i in range(len(property_text_lists))]))

它确实会产生这个输出。

text-value-A!text-value-B!text-value-C!text-value-D&text-value-A!text-value-B&text-value-C!text-value-A

【讨论】:

  • 它有效。感谢您的宝贵时间,并感谢您的详尽解释。
猜你喜欢
  • 2012-03-29
  • 2018-06-27
  • 1970-01-01
  • 2011-07-26
  • 1970-01-01
  • 2011-10-07
  • 2015-03-25
  • 1970-01-01
  • 2010-12-30
相关资源
最近更新 更多