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

2024-06-16 10:39:39 发布

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

我有一个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>

我想把它和一个列表进行比较:

[(('mango', 'FRUIT'), ('coconut', 'PLANT')),
 (('mango', 'PLANT'), ('coconut', 'PLANT')),
 ...
 (('apple', 'PLANT'), ('orange', 'FRUIT'), ('coconut', 'PLANT')),
 ...
 (('mango', 'FRUIT'), ('apple', 'FRUIT'), ('coconut', 'LIVING')),
 (('apple', 'PLANT'), ('orange', 'LIVING'), ('coconut', 'PLANT')), 
 ...
]

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;

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


Tags: 文件intoken元素appleforxmlthings
1条回答
网友
1楼 · 发布于 2024-06-16 10:39:39

这里有一个解决方案,让我知道它是否有帮助

from lxml import etree

doc = etree.parse('scratch.xml')
root = doc.getroot()
things = {}
compare_list = [
    (('mango', 'FRUIT'), ('coconut', 'PLANT')),
    (('mango', 'PLANT'), ('coconut', 'PLANT')),
    (('apple', 'PLANT'), ('orange', 'FRUIT'), ('coconut', 'PLANT')),
    (('mango', 'FRUIT'), ('apple', 'FRUIT'), ('coconut', 'LIVING')),
    (('apple', 'PLANT'), ('orange', 'LIVING'), ('coconut', 'PLANT')),
]

def func():
    # for each <things> tag
    for child in root.getchildren():
        l = []
        for node in child:

            # if the node tag inside <things> child is 'tokens'
            if node.tag == 'tokens':

                # for each 'token' in 'tokens'
                for token in node:

                    # for each tag inside 'token'
                    for item in token:

                        # store the tag name and text into a list
                        if item.tag == 'livingthing':
                            l.append((item.text, 'LIVING'))
                        else:
                            l.append((item.text, item.tag.upper()))

                        # convert the list into a tuple and checks if there is a similar tuple in compare_list
                        if tuple(l) in compare_list:
                            # return things count if found
                            return child.attrib['count']

print(func())

使用您提供的xml的输出是:

484

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

相关问题 更多 >