未从XML中提取python值

2024-05-14 00:17:38 发布

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

我有一个XML文件,其结构如下:

<root>
  <subroot id="someID">
    <val1 value="a"/>
    <val2 value="b"/>
    <val3 value="c"/>
    <val4 value="1"/>
    <val5 value="2"/>
    <val6 value="3"/>
    <otherval value="xyz"/>
  </subroot>
  <subroot id="anotherID">
    <val1 value="aa"/>
    <val2 value="bb"/>
    <val3 value="cc"/>
    <val4 value="11"/>
    <val5 value="22"/>
    <val6 value="33"/>
    <otherval value="xxyyzz"/>
  </subroot>
  .
  .
  .
  .
</root>

我试图检索每个标记中的值。例如,我想要的输出是:

val1=a
val2=b
val3=c
val4=1
val5=2
val6=3
otherval=xyz

下面是我的非工作代码,它生成空格,即val1="", val2=""...

def getValues(self):
    from xml.dom.minidom import parseString
    import json

    file = open('myfile.xml','r')
    data = file.read()
    dom = parseString(data)
    rows = dom.getElementsByTagName("root")[0].getElementsByTagName("subroot")
    valueString = ""
    for row in rows:
        valueString = valueString+json.dumps(
        {
        'val1': row.getAttribute("val1"),
        'val2': row.getAttribute("val2"),
        'val3': row.getAttribute("val3"),
        'val4': row.getAttribute("val4"),
        'val5': row.getAttribute("val5"),
        'val6': row.getAttribute("val6"),
        'other': row.getAttribute("otherval")},
        sort_keys=True,
        indent=4)+","
    response_generator = ( "["+valueString[:-1]+"]" )
    return HttpResponse(response_generator)
    otherval=xyz

我知道这实际上会产生JSON,但这并不重要。重要的是能够提取这些值,然后我就可以对它们做任何事情。你知道吗

有人能给我看看我缺了什么吗? 另外,我是否应该更改XML,使所有val1,val2,val3....都被称为val?你知道吗

谢谢。你知道吗


Tags: valuerootdomrowxyzval1subrootval2
3条回答

val1etc不是subroot行的属性。它们是子行,每个子行都有一个value属性,该属性包含所需的数据。您需要获取每个subroot的子级并遍历它们,对每个子级调用row.getAttribute("value")。你知道吗

正如Lattyware所说,是的,你应该重命名你的元素。你知道吗

>>> rows = dom.getElementsByTagName("root")[0].getElementsByTagName("subroot")

>>> v = rows[0].getElementsByTagName("val1")[0]

>>> v.getAttribute("value")
u'a'

我建议你使用ElementTree更容易理解。你知道吗

>>> import xml.etree.ElementTree as et
>>> root = et.fromstring(data)
>>> v = root.find("*/val1")
>>> v.get("value")
'a'

我的建议是按如下方式组织数据:

<root>
  <subroot id="someID">
    <value id="1">a</value>
    <value id="2">b</value>
    <value id="3">c</value>
    <value id="4">d</value>
    <value id="5">2</value>
    <value id="6">3</value>
    <value id="other">xyz</value>
  </subroot>
  <subroot id="anotherID">
    <value id="1">aa</value>
    <value id="2">bb</value>
    <value id="3">cc</value>
    <value id="4">11</value>
    <value id="5">22</value>
    <value id="6">33</value>
    <value id="other">xxyyzz</value>
  </subroot>
</root>

然后,为了解析,我建议使用etree库——它位于Python的标准库中,而且我发现使用它比使用其他库要好得多。这只是一个简单的例子,遍历子路径和值元素并提取数据。你知道吗

from xml.etree import ElementTree

xml = ElementTree.parse("test.xml")

root = xml.getroot()

all = {}

for group in root.findall("subroot"):
    temp = {}
    for value in group.findall("value"):
        temp[value.get("id")] = value.text
    all[group.get("id")] = temp

所有这些都将是:

{'someID': {'1': 'a', '3': 'c', '2': 'b', '5': '2', '4': 'd', '6': '3', 'other': 'xyz'}, 'anotherID': {'1': 'aa', '3': 'cc', '2': 'bb', '5': '22', '4': '11', '6': '33', 'other': 'xxyyzz'}}

您也可以作为dict comprehension执行此操作:

all = {group.get("id"): {value.get("id"): value.text for value in group.findall("value")} for group in root.findall("subroot")}

请注意,这是一个有点难以阅读,并会崩溃,如果你试图做任何更复杂的。你知道吗

相关问题 更多 >