如何使用Python处理XML中的键值对标签

2024-04-28 04:39:22 发布

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

使用以下XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<Environment
     xmlns="http://schemas.dmtf.org/ovf/environment/1"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:oe="http://schemas.dmtf.org/ovf/environment/1"
     xmlns:ve="http://www.vmware.com/schema/ovfenv"
     oe:id=""
     ve:vCenterId="vm-61">
   <PlatformSection>
      <Kind>VMware ESXi</Kind>
      <Version>5.5.0</Version>
      <Vendor>VMware, Inc.</Vendor>
      <Locale>en</Locale>
   </PlatformSection>
   <PropertySection>
         <Property oe:key="ppEnv" oe:value="production"/>
         <Property oe:key="pphostname" oe:value="coolhostname"/>
   </PropertySection>
   <ve:EthernetAdapterSection>
      <ve:Adapter ve:mac="00:50:56:94:9a:56" ve:network="Service" ve:unitNumber="7"/>
   </ve:EthernetAdapterSection>
</Environment>

我想得到oe:key "pphostname"的值,但我找不到一个明确的方法来实现这一点。在

我对python和xml还不熟悉,我所尝试的python就是:

^{pr2}$

我对bash比较熟悉,但是我不喜欢使用bash实用程序进行解析。在


Tags: keyorghttpenvironmentwwwvexmlschemas
3条回答

检查this document(第6.2节:命名空间默认)。在xml中,有一个默认的命名空间(xmlns=“http://schemas.dmtf.org/ovf/environment/1"). 所以我认为我们需要在xpath中添加默认名称空间。下面是测试代码,带有lxml库(libxml2应该类似)。在

from lxml import etree
from StringIO import StringIO

s = '''<?xml version="1.0" encoding="UTF-8"?>
<Environment
     xmlns="http://schemas.dmtf.org/ovf/environment/1"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:oe="http://schemas.dmtf.org/ovf/environment/1"
     xmlns:ve="http://www.vmware.com/schema/ovfenv"
     oe:id=""
     ve:vCenterId="vm-61">
   <PlatformSection>
      <Kind>VMware ESXi</Kind>
      <Version>5.5.0</Version>
      <Vendor>VMware, Inc.</Vendor>
      <Locale>en</Locale>
   </PlatformSection>
   <PropertySection>
         <Property oe:key="ppEnv" oe:value="production"/>
         <Property oe:key="pphostname" oe:value="coolhostname"/>
   </PropertySection>
   <ve:EthernetAdapterSection>
      <ve:Adapter ve:mac="00:50:56:94:9a:56" ve:network="Service" ve:unitNumber="7"/>
   </ve:EthernetAdapterSection>
</Environment>'''

f = StringIO(s)
tree = etree.parse(f)

namespaces={'oe': 'http://schemas.dmtf.org/ovf/environment/1', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance', 've': 'http://www.vmware.com/schema/ovfenv'}   

print tree.xpath('//oe:Property[@oe:key="pphostname"]/@oe:value', namespaces=namespaces)
#output ['coolhostname']

尝试使用xml.dom.minidom

from xml.dom import minidom

xml_doc = minidom.parse('test.xml')
property_items = xml_doc.getElementsByTagName("Property")

condition = lambda x: x.hasAttribute('oe:key') and 
                      x.attributes['oe:key'].value == "pphostname"

matched_elements = [x for x in property_items if condition(x)]

if matched_elements:
    matched_element = matched_elements[0]
    print matched_element.attributes['oe:value'].value

您只需为名称空间(oe)指定一个名称,并从它们的属性中匹配键值对。在

我使用xml模块的示例:

import xml.etree.ElementTree as ET

s = '''<?xml version="1.0" encoding="UTF-8"?>
<Environment
     xmlns="http://schemas.dmtf.org/ovf/environment/1"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:oe="http://schemas.dmtf.org/ovf/environment/1"
     xmlns:ve="http://www.vmware.com/schema/ovfenv"
     oe:id=""
     ve:vCenterId="vm-61">
   <PlatformSection>
      <Kind>VMware ESXi</Kind>
      <Version>5.5.0</Version>
      <Vendor>VMware, Inc.</Vendor>
      <Locale>en</Locale>
   </PlatformSection>
   <PropertySection>
         <Property oe:key="ppEnv" oe:value="production"/>
         <Property oe:key="pphostname" oe:value="coolhostname"/>
   </PropertySection>
   <ve:EthernetAdapterSection>
      <ve:Adapter ve:mac="00:50:56:94:9a:56" ve:network="Service" ve:unitNumber="7"/>
   </ve:EthernetAdapterSection>
</Environment>'''

tree = ET.fromstring(s)
oe = '{http://schemas.dmtf.org/ovf/environment/1}'

for node in tree.iter(oe+'Property'):
    if node.attrib[oe+'key'] == 'pphostname':
        print node.attrib[oe+'value']

结果:

^{pr2}$

相关问题 更多 >