【问题标题】:Display XML tree structure with BeautifulSoup用 BeautifulSoup 显示 XML 树结构
【发布时间】:2020-09-04 01:26:33
【问题描述】:

在使用新的 XML 结构时,首先了解全局总是很有帮助的。

使用BeautifulSoup加载时:

import requests, bs4
s = requests.get('https://www.w3schools.com/xml/cd_catalog.xml').text
x = bs4.BeautifulSoup(s, 'xml')
print(x)

有没有内置的方式来显示不同深度的树形结构?


https://www.w3schools.com/xml/cd_catalog.xml 的示例,maxdepth=0,它将是:

CATALOG

使用maxdepth=1,它将是:

CATALOG
  CD 
  CD
  CD
  ...

如果使用maxdepth=2,它将是:

CATALOG
  CD 
    TITLE
    ARTIST
    COUNTRY
    COMPANY
    PRICE
    YEAR
  CD 
    TITLE
    ARTIST
    COUNTRY
    COMPANY
    PRICE
    YEAR
  ...

【问题讨论】:

  • 不是你想要的,但我使用xmltodict 将 xml 解析为有序字典,可以递归查看到所需的深度。
  • 你能展示一个带有xmltodict@Aramakus 的代码示例吗? PS:xmltodict库有多个版本,你用的是哪个版本的?

标签: python xml beautifulsoup tree


【解决方案1】:

这里有一个快速的方法:使用prettify() 函数对其进行结构化,然后通过正则表达式获取缩进和开始标记名称(在这种情况下捕获开始标记内的大写单词)。如果pretify() 的压痕符合深度规范,则以指定的压痕尺寸打印。

import requests, bs4
import re

maxdepth = 1
indent_size = 2
s = requests.get('https://www.w3schools.com/xml/cd_catalog.xml').text
x = bs4.BeautifulSoup(s, 'xml').prettify()

for line in x.split("\n"):
    match = re.match("(\s*)<([A-Z]+)>", line)
    if match and len(match.group(1)) <= maxdepth:
        print(indent_size*match.group(1) + match.group(2))

【讨论】:

  • 不错的解决方案!也许我们应该有比&lt;([A-Z]+)&gt; 更多的东西来匹配小写等。&lt;opf:metadata&gt; 标签(在 EPUB 书籍中)
【解决方案2】:

我使用了xmltodict 0.12.0(通过 anaconda 安装),它完成了 xml 解析的工作,但不适用于深度查看。像任何其他字典一样工作。从这里开始,使用深度计数的递归应该是一种方法。

import requests, xmltodict, json

s = requests.get('https://www.w3schools.com/xml/cd_catalog.xml').text
x = xmltodict.parse(s, process_namespaces=True)

for key in x:
    print(json.dumps(x[key], indent=4, default=str))

【讨论】:

  • 谢谢!输出类似于OrderedDict([('CD', [OrderedDict([('TITLE', 'Empire Burlesque'), ('ARTIST', 'Bob Dylan'), ('COUNTRY', 'USA'), ('COMPANY', 'Columbia'), ('PRICE', '10.90'), ('YEAR', '1985')]), OrderedDict([('TITLE', 'Hide your heart'), ('ARTIST', 'Bonnie Tyler'), ('COUNTRY', 'U...,您将如何生成人类可读的树结构?
  • 我认为最简单的方法是print(json.dumps(x[key], indent=4, default=str)),当然你需要添加import json
【解决方案3】:

这是一种没有BeautifulSoup 的解决方案。

import requests
s = requests.get('https://www.w3schools.com/xml/cd_catalog.xml').text
array = []

tab_size = 2
target_depth = 2

for element in s.split('\n'):
    depth = (len(element) - len(element.lstrip())) / tab_size
    if depth <= target_depth:
        print(' ' * int(depth) + element)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多