如何在python中比较两个xpath

时间:2011-10-08 06:19:09

标签: python xpath compare

我有两个xpath字符串,例如:

/Envlope[1]/Header[1]/transactionInfo[1]/id[1]

/Envelope/Header/*

我如何比较(匹配)这个xpaht? 我如何在python上做这个或者更好用什么算法?

示例:

<?xml version="1.0" encoding="utf-8"?>
<Envelope>
    <Header>
        <transactionInfo>
            <id>31234</id>
        </transactionInfo>
    </Header>
    <Body>
        <message>test_31234</message>
    </Body>
</Envelope>

预期:

/Envlope[1]/Header[1]/transactionInfo[1]/id[1]

中的

/Envelope/Header/*

/Envlope[1]/Body[1]/message[1]不在/Envelope/Header/*

/Envlope[1]/Header[1]不在/Envelope/Header/*

1 个答案:

答案 0 :(得分:1)

使用lxml

import lxml.etree as ET

def is_descendant(tree,path1,path2):
    elt1=tree.xpath(path1)[0]
    elt2=tree.xpath(path2+'/descendant::*')
    return elt1 in elt2

content='''\
<?xml version="1.0" encoding="utf-8"?>
<Envelope>
    <Header>
        <transactionInfo>
            <id>31234</id>
        </transactionInfo>
    </Header>
    <Body>
        <message>test_31234</message>
    </Body>
</Envelope>
'''

tests=[
    ('/Envelope[1]/Header[1]/transactionInfo[1]/id[1]','/Envelope/Header/*'),
    ('/Envelope[1]/Body[1]/message[1]','/Envelope/Header/*'),
    ('/Envelope[1]/Header[1]','/Envelope/Header/*')    
    ]

tree=ET.fromstring(content)
for path1,path2 in tests:
    if is_descendant(tree,path1,path2):
        print('{p1} in {p2}'.format(p1=path1,p2=path2))
    else:
        print('{p1} NOT in {p2}'.format(p1=path1,p2=path2))

产量

/Envelope[1]/Header[1]/transactionInfo[1]/id[1] in /Envelope/Header/*
/Envelope[1]/Body[1]/message[1] NOT in /Envelope/Header/*
/Envelope[1]/Header[1] NOT in /Envelope/Header/*

PS。请注意,符号==通常是为对称关系保留的:如果X == YY == X。在这种情况下,您似乎在寻找不对称关系:Y包含X。因此,或许可以使用或某些符号或短语。