【问题标题】:XML searching pythonXML搜索python
【发布时间】:2015-04-02 12:41:39
【问题描述】:

我有一个下一个类型的 XML:

<OUTPUT>
    <HEADER>

    </HEADER>
    <REGISTER>
        <RESULT>0</RESULT>
        <KEY1>CAR</KEY1>
        <KEY2>RED</KEY2>
        <KEY3>2013</KEY3>
        <ATTRIBUTE1>2000</ATTRIBUTE1>
        <ATTRIBUTE2>100000</ATTRIBUTE2>
    </REGISTER>
    <REGISTER>
        <RESULT>0</RESULT>
        <KEY1>TRUCK</KEY1>
        <KEY2>BLUE</KEY2>
        <KEY3>2014</KEY3>
        <ATTRIBUTE1>3000</ATTRIBUTE1>
        <ATTRIBUTE2>400000</ATTRIBUTE2>
    </REGISTER>
<OUTPUT>

如果 KEY1、KEY2、KEY3 有一些值而不在 python 中循环,我如何搜索 ATTRIBUTE1 的值? (某种 c# 的 lambda 表达式)

感谢@CommuSoft,我知道我可以将 Xpath 查询与 libxml2 一起使用。但是当我尝试使用pip install libxml2-python 安装它时,我发现错误

Could not find any downloads that satisfy the requirement libxml2-python

另外我忘了提到我在 anaconda 和 windows 上使用 python 2.7。

【问题讨论】:

  • Lambda 表达式?我会使用 xpath 查询...
  • @CommuSoft 你能给我一个我给出的 xml 的例子吗?例如,如果 key1=TRUCK, KEY2=BLUE,KEY3=2014,如何搜索 ATTRIBUTE1 值?
  • 查看答案(使用 xpath)。

标签: python xml


【解决方案1】:

通常最好使用库处理 XML,在这种情况下特别是使用 XPath query

import libxml2

doc = libxml2.parseFile("tst.xml")
ctxt = doc.xpathNewContext()
res = ctxt.xpathEval("//REGISTER/ATTRIBUTE1[../KEY1/text()='TRUCK' and ../KEY2/text()='BLUE' and ../KEY3/text()='2014']")

doc.freeDoc()
ctxt.xpathFreeContext()

这里的查询是:

//REGISTER/ATTRIBUTE1[../KEY1/text()='TRUCK' and ../KEY2/text()='BLUE' and ../KEY3/text()='2014']

结果存储在res

【讨论】:

  • libxml2-python 是一个绑定,你是先安装sudo apt-get install libxml2-dev libxslt1-dev 吗?
  • 我正在使用 windows(据我所知,sudo 不适用于 windows)我必须执行什么命令?
  • @rlartiga:this 有帮助吗?
  • @rlartiga:你能用pip得到的错误更新你的问题吗?
  • 我删除了我的 cmets 并更新了答案,谢谢
【解决方案2】:

使用lxml with XPath

import lxml.etree as etree

x = """<OUTPUT>
    <HEADER>

    </HEADER>
    <REGISTER>
        <RESULT>0</RESULT>
        <KEY1>CAR</KEY1>
        <KEY2>RED</KEY2>
        <KEY3>2013</KEY3>
        <ATTRIBUTE1>2000</ATTRIBUTE1>
        <ATTRIBUTE2>100000</ATTRIBUTE2>
    </REGISTER>
    <REGISTER>
        <RESULT>0</RESULT>
        <KEY1>TRUCK</KEY1>
        <KEY2>BLUE</KEY2>
        <KEY3>2014</KEY3>
        <ATTRIBUTE1>3000</ATTRIBUTE1>
        <ATTRIBUTE2>400000</ATTRIBUTE2>
    </REGISTER>
</OUTPUT>"""

tree = etree.fromstring(x)
xpath = "//REGISTER[./KEY1/text()='TRUCK' and ./KEY2/text()='BLUE' and ./KEY3/text()='2014']/ATTRIBUTE1"
for attribute1 in tree.xpath(xpath):
    print(attribute1.text)

输出:

3000

【讨论】:

  • +1,但也许您可以使用/text() 作为条件?否则,如果它们也有属性,那就有问题了......
  • .text() 不被 lxml XPath 接受。这个./KEY3.text()='2014'XPathEvalError: Invalid expression :(
  • 不是.text(),而是/text()(带斜线)。
  • @CommuSoft 我也在尝试这个解决方案,如果我知道有一个具有该属性的注册表,是否有办法获取该值?
  • @rlartiga:我不明白这个问题......从语法上讲它没有多大意义,请重新表述?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多