在 Python 2.7.15 中使用 ElementTree 从 util:list 获取值

Getting values from util:list using ElementTree in Python 2.7.15

我在 python 2.7.15 上使用 etree,但我卡住了,我试图解析 XML 文件以从 it.As 获取值,您可以在下面查看我的代码:

# -*- coding: utf-8 -*-

import xml.etree.ElementTree as etree

def XMLParse(filename):
   filename = filename
   tree = etree.parse(filename)
   beans = tree.findall('{http://www.speedframework.org/schema/beans}bean')

   for bean in beans:
     for property in bean:

        if "name" in property.attrib and "value" in property.attrib:
            print ("This one catches PROP1:" + property.attrib['name'])
            print property.attrib

        if "name" in property.attrib and not "value" in property.attrib:
            for util in property.iter():
                for lists in util:
                    for parameter in lists:


                        if 'key' in parameter.attrib:
                            print ("This one catches PROP3:" + parameter.attrib['key'])

                        if 'bean' in parameter.attrib:
                            print ("This one catches PROP4:" + parameter.attrib['bean'])

                        if 'value' in parameter.attrib:
                            print ("This one should catch PROP2:" + parameter.attrib['value'])
                        print parameter.attrib


filename = open('static/test1.xml')
XMLParse(filename)

这是我的 xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.speedframework.org/schema/beans"
xmlns:cxf="http://cxf.apache.org/core" 
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:test="http://apache.org/hello_world_soap_http" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.speedframework.org/schema/util" 
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xmlns:sec="http://cxf.apache.org/configuration/security"
xmlns:context="http://www.speedframework.org/schema/context"
xsi:schemaLocation="
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd
http://www.speedframework.org/schema/beans
http://www.speedframework.org/schema/beans/speed-beans-2.0.xsd
http://www.speedframework.org/schema/context
http://www.speedframework.org/schema/context/speed-context-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://www.speedframework.org/schema/util
http://www.speedframework.org/schema/util/speed-util-2.0.xsd
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://cxf.apache.org/configuration/security
http://cxf.apache.org/schemas/configuration/security.xsd">

<context:property-placeholder location="classpath:realm.properties"/>

<bean id="FOO" class="BAR">
    <property name="Prop1" value="ValueProp1" />
    <property name="Prop2">
        <util:list>
            <value>PropValue2A</value>
            <value>PropValue2B</value>
        </util:list>
    </property>
    <property name="Prop3">
        <util:map>
            <entry key="Prop3Key" value-ref="Prop3Value" />
        </util:map>
    </property>
    <property name="Prop4">
        <util:list>
            <ref bean="Prop4" />
        </util:list>
    </property>
</bean>
</beans>

如您所见,prop1、prop3 和 prop 4 正在解析 fine.The 问题出在 prop2,当我尝试获取 property.attrib 我得到的所有内容时只是 {} {} 两个空的 brackets.My 真正的 xml 大得多,这就是我使用循环的原因。但也可能有更好的解决方案我正在考虑使用 xpath 吗?

输出:

This one catches PROP1:Prop1
{'name': 'Prop1', 'value': 'ValueProp1'}
{}
{}
This one catches PROP3:Prop3Key
{'value-ref': 'Prop3Value', 'key': 'Prop3Key'}
This one catches PROP4:Prop4
{'bean': 'Prop4'}

主要问题: 如何从 util:list 获取所有 "prop2"?

if 'value' in parameter.attrib:

我觉得这不对。假设 parameter 指的是 <value>PropValue2A</value> 元素。该标记是一个值元素,但它没有值属性。如果是这样,它看起来像:

<value value=whatever>PropValue2A</value>

我想你想在这种情况下检查元素的名称,而不是它的属性。

for parameter in lists:


    if 'key' in parameter.attrib:
        print ("This one catches PROP3:" + parameter.attrib['key'])

    if 'bean' in parameter.attrib:
        print ("This one catches PROP4:" + parameter.attrib['bean'])

    if 'value' in parameter.tag:
        print ("This one should catch PROP2:" + parameter.tag)
    print parameter.attrib

现在你的第三个条件将在遍历 Prop2 时通过两次:

This one catches PROP1:Prop1
{'name': 'Prop1', 'value': 'ValueProp1'}
This one should catch PROP2:{http://www.speedframework.org/schema/beans}value
{}
This one should catch PROP2:{http://www.speedframework.org/schema/beans}value
{}
This one catches PROP3:Prop3Key
{'value-ref': 'Prop3Value', 'key': 'Prop3Key'}
This one catches PROP4:Prop4
{'bean': 'Prop4'}

此外,我认为您的代码中的 for 循环太多了。您有五个 for 循环,但是 beans 元素的内容的最大标记深度只有四个。无论如何你都会得到合理的输出,因为 property.iter 遍历属于 属性 树的所有节点,包括它自己,所以在某些情况下循环有效地取消了。但是您可以通过仅遍历 property 的直接后代并跳过其中一个循环来简化事情。

import xml.etree.ElementTree as etree

def XMLParse(filename):
   filename = filename
   tree = etree.parse(filename)
   beans = tree.findall('{http://www.speedframework.org/schema/beans}bean')

   for bean in beans:
     for property in bean:

        if "name" in property.attrib and "value" in property.attrib:
            print ("This one catches PROP1:" + property.attrib['name'])
            print property.attrib

        if "name" in property.attrib and not "value" in property.attrib:
            for util in property:
                for parameter in util:
                    if 'key' in parameter.attrib:
                        print ("This one catches PROP3:" + parameter.attrib['key'])

                    if 'bean' in parameter.attrib:
                        print ("This one catches PROP4:" + parameter.attrib['bean'])

                    if 'value' in parameter.tag:
                        print ("This one should catch PROP2:" + parameter.tag)
                    print parameter.attrib


filename = open('data.xml')
XMLParse(filename)

你应该仍然得到相同的输出,而且会快一点。

This one catches PROP1:Prop1
{'name': 'Prop1', 'value': 'ValueProp1'}
This one should catch PROP2:{http://www.speedframework.org/schema/beans}value
{}
This one should catch PROP2:{http://www.speedframework.org/schema/beans}value
{}
This one catches PROP3:Prop3Key
{'value-ref': 'Prop3Value', 'key': 'Prop3Key'}
This one catches PROP4:Prop4
{'bean': 'Prop4'}