Python LXML Xpath似乎没有返回完整路径

Python LXML Xpath似乎没有返回完整路径,python,xpath,xml-parsing,lxml,Python,Xpath,Xml Parsing,Lxml,好吧,我会第一个承认它是,只是不是我想要的路径,我不知道如何得到它 我在Eclipse中使用Python3.3,在工作时在Windows7中使用Pydev插件,在家中在ubuntu 13.04中使用Pydev插件。我是python新手,编程经验有限 我正在尝试编写一个脚本,以接收XML Lloyds market insurance消息,找到所有标记并将它们转储到.csv中,在那里我们可以轻松地更新它们,然后重新导入它们以创建更新的XML 我已经设法做到了所有这些,除了当我得到所有的标签时,它只

好吧,我会第一个承认它是,只是不是我想要的路径,我不知道如何得到它

我在Eclipse中使用Python3.3,在工作时在Windows7中使用Pydev插件,在家中在ubuntu 13.04中使用Pydev插件。我是python新手,编程经验有限

我正在尝试编写一个脚本,以接收XML Lloyds market insurance消息,找到所有标记并将它们转储到.csv中,在那里我们可以轻松地更新它们,然后重新导入它们以创建更新的XML

我已经设法做到了所有这些,除了当我得到所有的标签时,它只给出标签名,而不是上面的标签

<TechAccount Sender="broker" Receiver="insurer">
<UUId>2EF40080-F618-4FF7-833C-A34EA6A57B73</UUId>
<BrokerReference>HOY123/456</BrokerReference>
<ServiceProviderReference>2012080921401A1</ServiceProviderReference>
<CreationDate>2012-08-10</CreationDate>
<AccountTransactionType>premium</AccountTransactionType>
<GroupReference>2012080921401A1</GroupReference>
<ItemsInGroupTotal>
<Count>1</Count>
</ItemsInGroupTotal>
<ServiceProviderGroupReference>8-2012-08-10</ServiceProviderGroupReference>
<ServiceProviderGroupItemsTotal>
<Count>13</Count>
</ServiceProviderGroupItemsTotal>
这使得:

'{http://www.ACORD.org/standards/Jv-Ins-Reinsurance/1}ServiceProviderGroupReference,8-2012-08-10', '{http://www.ACORD.org/standards/Jv-Ins-Reinsurance/1}ServiceProviderGroupItemsTotal,\n', '{http://www.ACORD.org/standards/Jv-Ins-Reinsurance/1}Count,13',
正如您所看到的,Count显示为{namespace}Count,13,而不是{namespace}ItemsInGroupTotal/Count,13

有人能告诉我需要什么吗

谢谢希望我的第一篇文章是好的

亚当

编辑:

这是我现在的代码: 使用openfullpath,“rb”作为xmlFilepath: xmlfile=xmlFilepath.read

fulltext = '%s' % xmlfile
text = fulltext[2:]
print(text)


xml = etree.fromstring(fulltext)
tree = etree.ElementTree(xml)

every_tag = ['%s, %s' % (tree.getpath(e), e.text) for e in xml.iter()]
print(every_tag)
但这会返回一个错误: ValueError:不支持带有编码声明的Unicode字符串。请使用无声明的字节输入或XML片段

我删除了前两个字符,因为你的是b'并且它抱怨它没有以标签开头

更新:

我一直在玩这个,如果我删除xis:xxx标记和顶部的名称空间内容,它就会像预期的那样工作。我需要保留xis标记,并能够将它们标识为xis标记,这样就不能删除它们

关于我如何实现这一点有什么帮助吗

ElementTree对象有一个方法getpathelement,该方法返回 用于查找该元素的结构化绝对XPath表达式

对循环中的每个元素调用getpath应该适合您:

from pprint import pprint
from lxml import etree


text = """
<TechAccount Sender="broker" Receiver="insurer">
    <UUId>2EF40080-F618-4FF7-833C-A34EA6A57B73</UUId>
    <BrokerReference>HOY123/456</BrokerReference>
    <ServiceProviderReference>2012080921401A1</ServiceProviderReference>
    <CreationDate>2012-08-10</CreationDate>
    <AccountTransactionType>premium</AccountTransactionType>
    <GroupReference>2012080921401A1</GroupReference>
    <ItemsInGroupTotal>
        <Count>1</Count>
    </ItemsInGroupTotal>
    <ServiceProviderGroupReference>8-2012-08-10</ServiceProviderGroupReference>
    <ServiceProviderGroupItemsTotal>
        <Count>13</Count>
    </ServiceProviderGroupItemsTotal>
</TechAccount>
"""

xml = etree.fromstring(text)
tree = etree.ElementTree(xml)

every_tag = ['%s, %s' % (tree.getpath(e), e.text) for e in xml.iter()]
pprint(every_tag)
UPD: 如果xml数据位于文件test.xml中,则代码如下所示:

from pprint import pprint
from lxml import etree

xml = etree.parse('test.xml').getroot()
tree = etree.ElementTree(xml)

every_tag = ['%s, %s' % (tree.getpath(e), e.text) for e in xml.iter()]
pprint(every_tag)
希望有帮助

ElementTree对象有一个方法getpathelement,该方法返回 用于查找该元素的结构化绝对XPath表达式

对循环中的每个元素调用getpath应该适合您:

from pprint import pprint
from lxml import etree


text = """
<TechAccount Sender="broker" Receiver="insurer">
    <UUId>2EF40080-F618-4FF7-833C-A34EA6A57B73</UUId>
    <BrokerReference>HOY123/456</BrokerReference>
    <ServiceProviderReference>2012080921401A1</ServiceProviderReference>
    <CreationDate>2012-08-10</CreationDate>
    <AccountTransactionType>premium</AccountTransactionType>
    <GroupReference>2012080921401A1</GroupReference>
    <ItemsInGroupTotal>
        <Count>1</Count>
    </ItemsInGroupTotal>
    <ServiceProviderGroupReference>8-2012-08-10</ServiceProviderGroupReference>
    <ServiceProviderGroupItemsTotal>
        <Count>13</Count>
    </ServiceProviderGroupItemsTotal>
</TechAccount>
"""

xml = etree.fromstring(text)
tree = etree.ElementTree(xml)

every_tag = ['%s, %s' % (tree.getpath(e), e.text) for e in xml.iter()]
pprint(every_tag)
UPD: 如果xml数据位于文件test.xml中,则代码如下所示:

from pprint import pprint
from lxml import etree

xml = etree.parse('test.xml').getroot()
tree = etree.ElementTree(xml)

every_tag = ['%s, %s' % (tree.getpath(e), e.text) for e in xml.iter()]
pprint(every_tag)
希望这能有所帮助。

getpath确实返回了不适合人类使用的xpath。通过这个xpath,您可以构建一个更有用的xpath。例如,使用这种快速而肮脏的方法:

def human_xpath(element):
    full_xpath = element.getroottree().getpath(element)
    xpath = ''
    human_xpath = ''
    for i, node in enumerate(full_xpath.split('/')[1:]):
        xpath += '/' + node
        element = element.xpath(xpath)[0]
        namespace, tag = element.tag[1:].split('}', 1)
        if element.getparent() is not None:
            nsmap = {'ns': namespace}
            same_name = element.getparent().xpath('./ns:' + tag,
                                                  namespaces=nsmap)
            if len(same_name) > 1:
                tag += '[{}]'.format(same_name.index(element) + 1)
        human_xpath += '/' + tag
    return human_xpath
getpath确实返回了不适合人类使用的xpath。通过这个xpath,您可以构建一个更有用的xpath。例如,使用这种快速而肮脏的方法:

def human_xpath(element):
    full_xpath = element.getroottree().getpath(element)
    xpath = ''
    human_xpath = ''
    for i, node in enumerate(full_xpath.split('/')[1:]):
        xpath += '/' + node
        element = element.xpath(xpath)[0]
        namespace, tag = element.tag[1:].split('}', 1)
        if element.getparent() is not None:
            nsmap = {'ns': namespace}
            same_name = element.getparent().xpath('./ns:' + tag,
                                                  namespaces=nsmap)
            if len(same_name) > 1:
                tag += '[{}]'.format(same_name.index(element) + 1)
        human_xpath += '/' + tag
    return human_xpath

非常感谢,但是我很难让它为我工作。我从文件中读取XML,而不是直接将其放入文本中,我试图将其转换为字符串的尝试似乎失败了。有什么建议吗?当然,用etree.parsefile_name替换etree.fromstringtext。对不起,我应该说我试过了,得到了:TypeError:参数'element'的类型不正确,应该是lxml.etree。_element,得到了lxml.etree。_ElementTreeThanks为了快速响应,您的更新代码对我有效,但输出:'/*、\n'、'/*/*、\n'、'/*/*/*/*/*[1],2EF40080-F618-4FF7-833C-A34EA6A57B73'、'/*/*/*/*[2]、HOY123/456'、'/*/*/*/*[3]等。这是否表明xml的格式化方式不符合我的要求?有没有办法发布整个xml?它有177行长,我可以将整个内容粘贴到问题中吗?是的,getpath无法处理带有名称空间的复杂xml。非常感谢,但我很难让它为我工作。我从文件中读取XML,而不是直接将其放入文本中,我试图将其转换为字符串的尝试似乎失败了。有什么建议吗?当然,用etree.parsefile_name替换etree.fromstringtext。对不起,我应该说我试过了,得到了:TypeError:参数'element'的类型不正确,应该是lxml.etree。_element,得到了lxml.etree。_ElementTreeThanks为了快速响应,您的更新代码对我有效,但输出:'/*、\n'、'/*/*、\n'、'/*/*/*/*/*[1],2EF40080-F618-4FF7-833C-A34EA6A57B73'、'/*/*/*/*[2]、HOY123/456'、'/*/*/*/*[3]等。这是否表明xml的格式化方式不符合我的要求?有没有一种方法可以发布整个xml?它有177行长,我可以粘贴问题中的全部内容吗?是的,getpath无法处理带有名称空间的复杂xml。这很有趣。我发现了类似的问题。我提出了一个问题,如何浏览并列出XML消息的XPATH?如何在发布的代码中插入人的xpath python函数?谢谢你的指导,很有趣。我发现了类似的问题。我提出了一个问题,如何浏览并列出XML消息的XPATH?如何在发布的代码中插入人的xpath python函数?谢谢你的指导。