使用BeautifulSoup循环遍历列表并创建XML标记

时间:2015-10-23 17:05:23

标签: python xml beautifulsoup

我有一份年份清单,如下:

year = ['2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013']

我正在尝试创建一系列XML标记,这些标记包含在另一个预先存在的标记中,如下所示:

<intro>
    <exposures>
      <exposure year = "2005"></exposure>
      <exposure year = "2006"></exposure>
      <exposure year = "2007"></exposure>
      <exposure year = "2008"></exposure>
      etc.
    <exposures> 
</intro>

稍后我将填充标签内的内容。现在我正在尝试遍历year并将它们添加到标记中,然后将其包含在标记内。

我一直在尝试遍历'year'列表,并将每个值作为属性附加到标记:

testsoup = BeautifulSoup(testxml, 'xml')
intro_tag = testsoup.intro('intro')
exp_tag = testsoup.exposures('exposures')
year = ['2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013']
exposure_tag = testsoup.new_tag('exposure', year = '')
for x in year:    
    exposure_tag['year'] = x
    exp_tag.append(exposure_tag)
    intro_tag.append(exp_tag)

不幸的是,这似乎只是附加了列表中的最后一个值:

<intro><exposures><exposure year="2013"/></exposures></intro>

这只是BeautifulSoup的一个特色吗?你能只添加一个标签而不是多个标签吗?我正在使用BeautifulSoup 4.4.0。

顺便说一句,BeautifulSoup是最好的方法吗?我看到很多帖子称赞BS4和lxml的网页编写能力,但似乎都没有用于生成XML(这不是一件坏事,只是我注意到的事情)。是否有更好的自动化XML生成包?

2 个答案:

答案 0 :(得分:2)

我怀疑问题是这一行:exposure_tag = testsoup.new_tag('exposure', year = '')。您有一个标记,并且您尝试将其多次附加到同一父级。试试这个。

for x in year:    
    exposure_tag = testsoup.new_tag('exposure', year = x)
    exp_tag.append(exposure_tag)
    intro_tag.append(exp_tag)

答案 1 :(得分:1)

我没有查看BS源代码,但认为行为是这样的:当你调用exp_tag.append(smth)时,你实际上添加了指向smth对象的指针。因此,当您仅实例化exposure_tag一次时,您会收到一堆指向同一对象的指针。当您在exposure_tag['year'] = x中修改该对象时,它会影响BS的内部列表结构的所有元素。

因此,解决方案是在每个步骤中创建新的对象实例:

testsoup = BeautifulSoup(testxml, 'xml')
intro_tag = testsoup.intro('intro')
exp_tag = testsoup.exposures('exposures')
year = ['2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013']
for x in year:    
    exposure_tag = testsoup.new_tag('exposure', year = x)
    exp_tag.append(exposure_tag)
    intro_tag.append(exp_tag)  # BTW: Are you sure you need this here?