【问题标题】:Handle 1 to n elements处理 1 到 n 个元素
【发布时间】:2014-12-15 15:10:17
【问题描述】:

我正在使用 xmltodict 来解析 XML 配置。 XML 具有结构,其中一个元素可以出现在 1 到 n 个实例中,其中两个都是有效的:

<items>
    <item-ref>abc</item-ref>
</items>

<items>
    <item-ref>abc</item-ref>
    <item-ref>dca</item-ref>
    <item-ref>abb</item-ref>
</items>

我用 xmltodict 解析这个如下:

document['items']['item-ref']

它会返回一个 unicode 或一个列表(取决于找到的项目),所以我总是需要添加一个额外的检查来确保我是否需要处理一个列表或一个字符串:

if isinstance(document['items']['item-ref'], list):
    my_var = document['items']['item-ref']
else:
    my_var = [document['items']['item-ref']] #create list manually

是否有更好/更简单/更优雅的方式来处理这些问题?

【问题讨论】:

  • 遇到了同样的问题,并检查了所有内容:)
  • 如果你想让你的手有点脏,你可以修补xmltodict.py。有一个方法,_DictSAXHandler.push_data,它决定哪些元素变成列表。您可以更改参数,以便您可以将一组元素传递给解析器总是变成一个列表。

标签: python xml xmltodict


【解决方案1】:

我不确定是否有一种超级优雅的方式来做到这一点。 Python 没有任何内置方法或函数可以帮助您在一行代码中完成此操作。然而,为了整合代码,您将需要做一些事情。正如 matsjoyce 在评论中提到的那样,您可能只是想创建一个为您处理此逻辑的函数。

def listn(val=None):
    if val is None:
        return []
    return val if isinstance(val, list) else [val]

>>> listn([1, 2, 3])
[1, 2, 3]
>>> listn()
[]
>>> listn(3)
[3]

现在您可以简单地使用您的 val 调用该函数并期望返回 list,无论是 listint 还是 NoneType 对象:

my_var = listn(document['items']['item-ref'])

(我的第一个答案创建了 list 的子类,但这需要 6 行而不是 4 行,并且会更改 type——这不是最理想的副作用。)

【讨论】:

  • 作为一个函数不是更好吗?您可以单线完成:listify=lambda x: x if isinstance(x, list) else [x]
  • 很公平。我不确定我是否会使用单线,但函数肯定会更容易,特别是如果它还可以容纳 None 值。我更新了上面的答案。
  • 这是一个让我的代码变得更加简单和紧凑的好方法。
  • @balas 很高兴它对你有用。好问题!我希望有一种更原生的方式来做到这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-16
相关资源
最近更新 更多