【问题标题】:Split a string value from JSON field and assign to YAML map从 JSON 字段中拆分字符串值并分配给 YAML 映射
【发布时间】:2019-05-04 07:38:17
【问题描述】:

我想将一个字符串拆分为多个部分并将其分配给 YAML 文件中的字段。这是我的 JSON 文件。

{
 "App Name": "blah", 
 "Email": "blah@blah.com", 
 "Employee ID": "xyz", 
 "Load Balancing Method": "Round Robin", 
 "Network": "CMN", 
 "Pool Member": "pucq-spn-198 5001/tcp\r\npucq-spn-199 5002/tcp\r\npucq-spn-200 
  5003/tcp", 
 "Pool Monitor": "tcp", 
 "Pool name": "pool", 
 "SSL": "Required", 
 "VIP Name": "vs-ng"
}

这是用户从 Web 表单提交的输入,我正在通过 API 访问它。我想将Pool Member字段中的值拆分为pucq-spn-1985001pucq-spn-1995002等字符串,并将它们分配给YAML文件中的不同字段。这是我的 YAML 文件。

nodes:
- description: PU
  host: 10.10.10.10
  monitors:
  - /Common/icmp
  name: node
- description: PU
  host: 10.10.10.10
  monitors:
  - /Common/icmp
  name: node-puex
partition: Common
pool:
  descriptions: PUE
  lb_method: Round Robin
  monitors:
  - /Common/tcp
  name: pool
pool_members:
- node_name: **pucq-spn-198**
  port: **5001**
- node_name: **pucq-spn-199**
  port: **5002**
server: gmly-p-01.blah.com
virtual_server:
  destination: 1.1.1.1
  ip_protocol: udp
  name: vs-ng
  pool: pool-pu-ind
  port: 999
  profiles:
  - name: fastL4
  type: performance-l4

我想将-node_name:port 中的值放在pool_members: 下。到目前为止,我尝试过这样的事情。但它不起作用。

import json
import requests
import yaml

url = "http://127.0.0.1:5000/vip7.json"
r = requests.get(url)
json_file = json.loads(r.content)
j = json_file

with open('C:/pytest/vs-test.yml', 'r') as f:
    y = yaml.load(f)

# Assign JSON values to YAML

y['pool']['lb_method'] = j['Load Balancing Method']
y['pool']['name'] = j['Pool name']
y['virtual_server']['name'] = j['VIP Name']

y['pool_members']['node_name'] = j[0]['Pool Member']
print (y['pool_members']['node_name'])

什么都不做。

也尝试过拆分。它打印出pucq-spn-198的部分。

pool = j['Pool Member']
p = pool.split()
y['pool_members']['node_name'] = pool[0:12]
print (pool[0:12])

但是当我像这样分配它y['pool_members']['node_name'] = pool[0:12] 它不起作用。

【问题讨论】:

  • 您的 API 似乎在本地主机上,因此您可以控制 JSON 形状...为什么不在 JSON 中创建嵌套对象而不是扁平字符串?
  • @cricket_007 是的,我考虑过,但即便如此,我也必须将其拆分并分别获取 pucq-spn-1985001
  • 你不打算这样做吗?我的意思是让服务器做,如果可能的话
  • @cricket_007 这是我用来创建 JSON 的代码 if form.validate_on_submit(): with open(new_path,'w') as j: json.dump(data, j) 我对 Python 很陌生,如果你能帮我创建嵌套对象并把 @ 987654340@ 和 5001 作为单独的对象,那就太好了:)
  • 如果我打印pool member,它会逐行打印出来。 \r\n 不打印。所以我们在那里很好。不幸的是,他们不想编辑 WebForm :(

标签: python json python-3.x parsing yaml


【解决方案1】:

我不确定您要强调的确切问题,但是

  1. y['pool_members'] = pool_members 应该会产生一些东西

  2. 我不认为[0:12] 是正确的,当您只需要输出中的 3 个元素并且只有 6 em> 拆分给定成员字符串值后的元素。

如果你想迭代成对的值,一种方法是创建一个生成器函数。

您应该执行的操作的完整示例如下所示:

import json
import yaml 
from pprint import pprint

# defining the input data 
data = {
 "App Name": "blah", 
 "Email": "blah@blah.com", 
 "Employee ID": "xyz", 
 "Load Balancing Method": "Round Robin", 
 "Network": "CMN", 
 "Pool Member": "pucq-spn-198 5001/tcp\r\npucq-spn-199 5002/tcp\r\npucq-spn-200 5003/tcp", 
 "Pool Monitor": "tcp", 
 "Pool name": "pool", 
 "SSL": "Required", 
 "VIP Name": "vs-ng"
}

# Parse the input data and make sure there are even names and ports after a split
pool_members = data['Pool Member'].split()
amt = len(pool_members)
if amt % 2 != 0:
  raise Exception("Not all pool members have a name and port!")
# create a lazy iterator over the list
gen = (pm for pm in pool_members)
# Creates a list of key-value pairs 
pool_members = [{"node_name": next(gen), "port" : next(gen)} for _ in range(amt // 2)]

# Generating the YAML
'''
loading a yaml file just makes a dict, so pretend there 
was previously any pool members before, or an empty list
'''
yaml_data = {"pool_members": []}
print(3 * "-")
yaml_data["pool_members"] = pool_members
# TODO: Write YAML to file instead of console
print(yaml.dump(yaml_data, default_flow_style=False))

这会输出以下内容:

---
pool_members:
- node_name: pucq-spn-198
  port: 5001/tcp
- node_name: pucq-spn-199
  port: 5002/tcp
- node_name: pucq-spn-200
  port: 5003/tcp

【讨论】:

  • 像魅力一样工作。再问一个问题,我先走了。假设我在池成员中有 4 行 而不是 JSON 文件中的 3 行,我如何在 node_nameport 的 YAML 中创建附加行?因为这里我们只显式地映射了 3 行,但是如果还有更多呢?您能否建议对上述代码进行修改以使其动态化? :)
  • 我从未明确定义过任何大小限制...(3 * "-") 与行数无关,它是 YAML 的事情,以文件的三个破折号开头...仅输入验证是长度是均匀的。如果数据中有另一个名称和端口,它将成为生成器的一部分,因此是输出的一部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2020-12-01
  • 2013-12-15
  • 2012-01-17
  • 1970-01-01
相关资源
最近更新 更多