如何将多个XML元素解析为一个字符串?

时间:2018-04-16 20:22:02

标签: python xml pandas

考虑以下只包含两个名为XML的节点的Mydoc

<?xml version="1.0" encoding="UTF-8" ?>
<Mydoc Time="2017-01-02"
    Period="2017-01-03">
    <mycontent ClassID="kinder">
        <bibliography>
            <Id>
                <Num>123456</Num>
            </Id>
                <Body>
this is some crazy text my friend
                </Body>
                <myreaders>
                    <names>
                        <Id>john</Id>
                        <value>95</value>
                    </names>
                </myreaders>
                <school>
                    <myclass>
                        <Id>12</Id>
                        <name>Laura</name>
                    </myclass>
                    <myclass>
                        <Id>14</Id>
                        <name>Frank</name>
                    </myclass>
                    <myclass>
                        <Id>144</Id>
                        <name>Jonny</name>
                    </myclass>
                    <myclass>
                        <Id>222</Id>
                        <name>Alex</name>
                    </myclass>
                    <myclass>
                        <Id>5443</Id>
                        <name>Johnny Doe</name>
                    </myclass>
                </school>
        </bibliography>
</mycontent>
    <mycontent ClassID="preK">
        <bibliography>
            <Id>
                <Num>123456</Num>
            </Id>
                <Body>
this is another crazy text my friend
                </Body>
                <myreaders>
                    <names>
                        <Id>fritz</Id>
                        <value>133</value>
                    </names>
                </myreaders>
        </bibliography>
</mycontent>
</Mydoc>

我正在尝试使用xml.etree对其进行解析,并将每个节点mydoc放入Pandas数据框中的单行中。

但是,正如您所看到的,我想将多个名为myclass的元素合并到我的数据帧的一个单元格中。

例如,预期输出(Pandas数据框两行两列)将类似于:

myreaders      school
"(john-95)"  "(12-Laura),(14-Frank),(144-Johnny),(222-Alex),(5443-Johnny Doe)"
"(fritz-133)" ""

我尝试使用xpath,但我无法将xpath次查询合并到"(12-Laura),(14-Frank),(144-Johnny),(222-Alex),(5443-Johnny Doe)"

等字符串化列表中

有什么建议吗?

谢谢!

4 个答案:

答案 0 :(得分:1)

您可以尝试XmlToDict,并将您的XML解析为词典/列表,它可以使您尝试做的更容易。 然后你可以循环/通过什么是myclass字典列表。 希望有所帮助。

答案 1 :(得分:1)

它变成了列表理解装置,但我认为这就是你所需要的。

import xml.etree.ElementTree as ET
import pandas as pd
tree = ET.parse('test.xml')
root = tree.getroot()
dicty = {}
dicty['myreaders'] = [','.join(['(' + x.findall('Id')[0].text + '-' + x.findall('value')[0].text + ')' for x in (root.findall('.//mycontent/bibliography/myreaders/names'))])]
dicty['school'] = [','.join(['(' + x.findall('Id')[0].text + '-' + x.findall('name')[0].text + ')' for x in (root.findall('.//mycontent/bibliography/school/myclass'))])]
print(dicty)
print(pd.DataFrame(dicty))

输出:

   myreaders                                             school
0  (john-95)  (12-Laura),(14-Frank),(144-Jonny),(222-Alex),(...

没有真正简单的方法来解析xml,你需要对数据结构有很多了解。

答案 2 :(得分:1)

你考虑过使用lxml模块吗?它有一些非常方便的方法来解析和遍历xml文件。 例如,我尝试了以下findall-lists并将它们组合在一起,然后您可以将它们添加到记录的“其余”中:

from lxml import etree
root = etree.parse(path_to_xml_file)
ids = [i.text for i in root.findall(".//myclass/Id")]
names = [n.text for n in root.findall(".//myclass/Name")]
comb = list(zip(ids,names))

这会给你:

[('12', 'Laura'), ('14', 'Frank'), ('144', 'Jonny'), ('222', 'Alex')]

答案 3 :(得分:1)

与其他答案类似,位更短,适用于新添加的节点:

parsedXML = ET.parse( "sample.xml")
root = parsedXML.getroot()
pairs0 = []
pairs1 = []
for mycontent in root.iter('mycontent'):
    pairs0.append(','.join(['(' + name[0].text + '-' + name[1].text + ')' for name in mycontent.iter('names')]))
    pairs1.append(','.join(['(' + myclass[0].text + '-' + myclass[1].text + ')' for myclass in mycontent.iter('myclass')]))
df = pd.DataFrame(data = {"myreaders": pairs0, "school": pairs1}, columns=['myreaders', 'school'])

编辑:重写以解决多个案例。