从JSON输出中切片并提取特定值

huangapple go评论68阅读模式
英文:

Slice and extract specific values from JSON output

问题

我正在查询一个REST API,我需要从适配器输出中选择2个字段,查询将包括多个事件编号。

我基本上需要一个事件编号和描述的列表,从下面的输出中获取。

获取数据的代码:

response = requests.post('http://dev.startschools.local:2031/baocdp/rest/process/:ITSM_Interface:IncidentManagement:QueryIncident/execute', headers=headers, data=json.dumps(get_query_inc_json()))
 
print(response.text)```

响应文本打印输出:

```[{"name":"Adapter_Output","value":"<query-action-result><entries><metadata><entry-count>2</entry-count></metadata><entry id=\"INC000003197686|INC000003197686\"><field name=\"Incident Number\">INC000021</field><field name=\"Description\">Student needs a new card issued</field></entry><entry id=\"INC000003198967|INC000003198967\"><field name=\"Incident Number\">INC000035</field><field name=\"Description\">Students cannot access the text book portal</field></entry></entries></query-action-result>"}]```

我需要获取一个事件编号和描述的列表,这样我就可以循环遍历它们:

事件编号列表1:

```["INC000021", "INC000035"]```

描述列表2:

```["Student needs a new card issued", "Students cannot access the text book portal"]```

我正在尝试使用切片将所有事件编号放入列表中,但由于输出不断变化,切片无法正常工作。

有人知道除了切片之外,还有更高效的方法来从这个输出中提取我需要的信息吗?

<details>
<summary>英文:</summary>

I am querying a REST API and I need to select 2 fields from the adapter output below, the query will include multiple incident numbers.

I basically need a list of Incident Numbers and Descriptions from the output below.

Code to get the data:

headers = {'content-type': 'application/json', 'Authentication-Token': authToken}
response = requests.post('http://dev.startschools.local:2031/baocdp/rest/process/:ITSM_Interface:IncidentManagement:QueryIncident/execute', headers=headers, data=json.dumps(get_query_inc_json()))

print(response.text)


response.text printed Output:

[{"name":"Adapter_Output","value":"<query-action-result><entries><metadata><entry-count>2</entry-count></metadata><entry id=&quot;INC000003197686|INC000003197686&quot;><field name=&quot;Incident Number&quot;>INC000021</field><field name=&quot;Description&quot;>Student needs a new card issued</field></entry><entry id=&quot;INC000003198967|INC000003198967&quot;><field name=&quot;Incident Number&quot;>INC000035</field><field name=&quot;Description&quot;>Students cannot access the text book portal</field></entry></entries></query-action-result>"}]


I need to get a list of Incident numbers and descriptions so I can loop through them:

List 1 of incident numbers:

["INC000021", "INC000035"]


List 2 of Descriptions:

["Student needs a new card issued", "Students cannot access the text book portal"]


I am trying to use slice to get all the incident numbers into a list but because the output keeps changing the slice is not working.

Anyone know of a more efficient way other than slice to extract the info I need from this output?

</details>


# 答案1
**得分**: 1

尝试这个。

data = response.text

value = data[0]["value"]
i_nums = [x.split("</field")[0] for x in value.split('<field name="Incident Number">')[1:]]
desc = [x.split("</field")[0] for x in value.split('<field name="Description">')[1:]]

print(i_nums)
print(desc)

<details>
<summary>英文:</summary>

  Try this. 
  
    data = response.text

    value = data[0][&quot;value&quot;]
    i_nums = [x.split(&quot;&lt;/field&quot;)[0] for x in value.split(&#39;&lt;field name=\&quot;Incident Number\&quot;&gt;&#39;)[1:]]
    desc = [x.split(&quot;&lt;/field&quot;)[0] for x in value.split(&#39;&lt;field name=\&quot;Description\&quot;&gt;&#39;)[1:]]

    print(i_nums)
    print(desc)

</details>



# 答案2
**得分**: 1

即使 @jjislam 的答案给出了你例子的正确答案,我仍建议你使用适当的 XML 解析器来浏览你的结果,因为这实际上是首次使用结构化数据的意图!

这是如何使用内置的 `xml.etree` 包的片段。一旦你理解这里发生了什么,你可以很容易地将其转换为使用推导实现的单行代码。

导入 xml.etree.ElementTree

响应文本 = [{"name":"Adapter_Output","value":"<query-action-result><entries><metadata><entry-count>2</entry-count></metadata><entry id=\&quot;INC000003197686|INC000003197686\&quot;><field name=\&quot;Incident Number\&quot;>INC000021</field><field name=\&quot;Description\&quot;>Student needs a new card issued</field></entry><entry id=\&quot;INC000003198967|INC000003198967\&quot;><field name=\&quot;Incident Number\&quot;>INC000035</field><field name=\&quot;Description\&quot;>Students cannot access the text book portal</field></entry></entries></query-action-result>"}]

# 根将是最顶层元素,在本例中是带有标签 &quot;query-action-result&quot; 的元素
root = xml.etree.ElementTree.fromstring(responseText[0][&quot;value&quot;])
事件,描述 = [] 

# 递归地遍历根元素的所有标签为 &quot;entry&quot; 的元素,这些元素是根元素的子元素
对于条目中的条目: 
  # 在每个条目中,找到第一个标签为 &quot;field&quot; 且属性为 &quot;name=Incident Number&quot; 的元素,并捕获其内容
  事件 = 条目.find(&quot;field[@name=&#39;Incident Number&#39;]&quot;).text
  # 同样,但属性为 &quot;name=Description&quot;
  描述 = 条目.find(&quot;field[@name=&#39;Description&#39;]&quot;).text
  打印(事件,描述)
  事件.append(事件)
  描述.append(描述)

打印(事件)
打印(描述)

<details>
<summary>英文:</summary>

Even though @jjislam&#39;s answer gives you the right answer for your example, I would recommend you to make use of a proper xml parser to navigate through your result, because this is the actual intent of having structured data in the first place!

This is a snippet on how to use the built-in `xml.etree` package. Once you get what is going on here, you can easily convert it into a single-liner with comprehensions.

    import xml.etree.ElementTree

    responseText = [{&quot;name&quot;:&quot;Adapter_Output&quot;,&quot;value&quot;:&quot;&lt;query-action-result&gt;&lt;entries&gt;&lt;metadata&gt;&lt;entry-count&gt;2&lt;/entry-count&gt;&lt;/metadata&gt;&lt;entry id=\&quot;INC000003197686|INC000003197686\&quot;&gt;&lt;field name=\&quot;Incident Number\&quot;&gt;INC000021&lt;/field&gt;&lt;field name=\&quot;Description\&quot;&gt;Student needs a new card issued&lt;/field&gt;&lt;/entry&gt;&lt;entry id=\&quot;INC000003198967|INC000003198967\&quot;&gt;&lt;field name=\&quot;Incident Number\&quot;&gt;INC000035&lt;/field&gt;&lt;field name=\&quot;Description\&quot;&gt;Students cannot access the text book portal&lt;/field&gt;&lt;/entry&gt;&lt;/entries&gt;&lt;/query-action-result&gt;&quot;}]
 
    # the root will be the topmost element, in this case the one with tag &quot;query-action-result&quot;
    root = xml.etree.ElementTree.fromstring(responseText[0][&quot;value&quot;])
    incidents, descriptions = [], []

    # iterate recursively over all elements with tag &quot;entry&quot; that are children of the root element
    for entry in root.iter(&#39;entry&#39;): 
        # within each entry, find the first element with tag &quot;field&quot; and attribute &quot;name=Incident Number&quot;, and capture its content
        incident = entry.find(&quot;field[@name=&#39;Incident Number&#39;]&quot;).text
        # same, but with attribute &quot;name=Description&quot;
        description = entry.find(&quot;field[@name=&#39;Description&#39;]&quot;).text
        print(incident, description)
        incidents.append(incident)
        descriptions.append(description)

    print(incidents)
    print(descriptions)

</details>



huangapple
  • 本文由 发表于 2023年3月20日 22:58:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75791909.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定