Python 将父标记内的XML节点值与元组序列作为列表中的元素进行比较

Python 将父标记内的XML节点值与元组序列作为列表中的元素进行比较,python,xml,list,for-loop,comparison,Python,Xml,List,For Loop,Comparison,我有一个XML文件,如下所示: <?xml version="1.0"?> <root> <things count="720"> <tokens> <token> <fruit>mango</fruit> </token> <token> <fruit>apple</fruit> </token> </to

我有一个XML文件,如下所示:

<?xml version="1.0"?>
<root>
<things count="720">
  <tokens>
   <token>
    <fruit>mango</fruit>
   </token>
  <token>
   <fruit>apple</fruit>
  </token>
 </tokens>
 <indices> ... </indices>
</things>

<things count="484">
 <tokens>
  <token>
   <fruit>mango</fruit>
  </token>
  <token>
  <plant>coconut</plant>
  </token>
 </tokens>
 <indices> ... </indices>
</things>

<things count="455">
 <tokens>
  <token>
   <fruit>mango</fruit>
  </token>
  <token>
   <fruit>apple</fruit>
  </token>
  <token>
   <livingthing>
    coconut
    <subtoken>
     <fruit>cocunut</fruit>
     <fruit>drycocunut</fruit>
    </subtoken>
   </livingthing>
  </token>
 </tokens>
 <indices> ... </indices>
</things>

...

</root>
xml节点(标记)与任何列表元素内元组的第二个元素之间的映射为:

  • 水果-->水果
  • 工厂-->工厂
  • 生活-->生活
  • 生活
现在,目标是逐个迭代XMLThings元素,并查找列表中是否有匹配项。为此,我们必须使用上述映射查看相应的标记,然后比较文本序列是否相同。如果存在匹配项,我们需要返回xml文件中相应things元素的订单号

我已经尝试编写了一个for循环,它迭代XML文件元素(子元素)以定位相关标记,然后使用内部for循环迭代每个列表元素以进行比较。一旦找到匹配项,两个循环都应终止。到目前为止,我的代码只适用于某些情况。要处理更复杂或边缘的情况,代码要么太硬,要么太复杂

因此,欢迎对这一问题采取新的办法

from lxml import etree 
doc = etree.parse(<path_to_xml_file>)
root = doc.getroot()

numThings= len(root.getchildren())

for i in range(numThings):
    toks = root[i]

    numTokens = len(toks.getchildren())
    for j in range(numTokens):

        tok = toks[j]
        numToks = len(tok.getchildren())

        for k in range(numToks):
            t = tok[k]
            numVals = len(t.getchildren())
            if t.tag != 'indices':

                flagMatch = False
                for tupseq in lstTupSeq:
                    for l in range(len(tupseq)):
                        te = tupseq[l]

                        v = t[l]
                        if te[0] == v.text and te[1].lower() in v.tag:
                            flagMatch = True
                        else:
                            flagMatch = False
                            break;
                    if flagMatch:
                        print(tupseq, i, j, k)
                        break;
从lxml导入etree
doc=etree.parse()
root=doc.getroot()
numThings=len(root.getchildren())
对于范围内的i(numThings):
toks=根[i]
numTokens=len(toks.getchildren())
对于范围内的j(numTokens):
tok=toks[j]
numToks=len(tok.getchildren())
对于范围内的k(numToks):
t=tok[k]
numVals=len(t.getchildren())
如果t.tag!='索引':
flagMatch=False
对于lstupseq中的tupseq:
对于范围内的l(len(tupseq)):
te=tupseq[l]
v=t[l]
如果te[0]==v.text和te[1].lower()位于v.tag中:
flagMatch=True
其他:
flagMatch=False
打破
如果flagMatch:
打印(tupseq,i,j,k)
打破

比较的预期输出应该是xml文件中匹配项的顺序号。在上面的示例中,当发现XML文件中的第三个元素(things count=“455”)与列表元素“('mango','FRUIT'),('apple','FRUIT'),('couch','LIVING')”匹配时,它应该返回一个3的输出。

这里有一个解决方案,请告诉我它是否有用

从lxml导入etree
doc=etree.parse('scratch.xml')
root=doc.getroot()
事物={}
比较列表=[
(‘芒果’、‘水果’、(‘椰子’、‘植物’),
(‘芒果’、‘植物’、(‘椰子’、‘植物’),
("苹果","植物","橘子","水果","椰子","植物",
((‘芒果’、‘水果’、(‘苹果’、‘水果’)、(‘椰子’、‘鲜活的’),
(‘苹果’、‘植物’、‘橘子’、‘活的’、‘椰子’、‘植物’),
]
def func():
#对于每个标签
对于root.getchildren()中的子级:
l=[]
对于子节点中的节点:
#如果子节点中的节点标记为“tokens”
如果node.tag==“令牌”:
#对于“令牌”中的每个“令牌”
对于节点中的令牌:
#对于“令牌”内的每个标记
对于令牌中的项目:
#将标记名和文本存储到列表中
如果item.tag==“livingthing”:
l、 追加((item.text,'LIVING'))
其他:
l、 追加((item.text,item.tag.upper())
#将列表转换为元组,并检查比较列表中是否有类似的元组
如果比较列表中的元组(l):
#如有发现,请归还物品
返回child.attrib['count']
打印(func())
使用您提供的xml的输出为:

484

它会打印找到的第一个匹配项。

这里有一个解决方案,如果有帮助,请告诉我

从lxml导入etree
doc=etree.parse('scratch.xml')
root=doc.getroot()
事物={}
比较列表=[
(‘芒果’、‘水果’、(‘椰子’、‘植物’),
(‘芒果’、‘植物’、(‘椰子’、‘植物’),
("苹果","植物","橘子","水果","椰子","植物",,
((‘芒果’、‘水果’、(‘苹果’、‘水果’)、(‘椰子’、‘鲜活的’),
(‘苹果’、‘植物’、‘橘子’、‘活的’、‘椰子’、‘植物’),
]
def func():
#对于每个标签
对于root.getchildren()中的子级:
l=[]
对于子节点中的节点:
#如果子节点中的节点标记为“tokens”
如果node.tag==“令牌”:
#对于“令牌”中的每个“令牌”
对于节点中的令牌:
#对于“令牌”内的每个标记
对于令牌中的项目:
#将标记名和文本存储到列表中
如果item.tag==“livingthing”:
l、 追加((item.text,'LIVING'))
其他:
l、 追加((item.text,item.tag.upper())
#将列表转换为元组,并检查比较列表中是否有类似的元组
如果比较列表中的元组(l):
#如有发现,请归还物品
返回child.attrib['count']
打印(func())
使用您提供的xml的输出为:

484

它打印出找到的第一根火柴。

非常感谢你,乔!我喜欢将xml节点值转换为元组的新方法,将其插入列表,然后检查另一个列表中是否有类似的元组。这很好用。:)我很高兴能帮上忙。非常感谢你,乔!我喜欢将xml节点值转换为元组的新方法,将其插入列表,然后检查另一个列表中是否有类似的元组。这很好用。:)我很高兴能帮上忙。