如何在空手道框架中获取子元素
How to get Child elements in Karate framework
我需要从一个 api 的响应中提取子元素,然后将其动态传递给下一个 api 请求。
假设我有以下 xml:
* def foo =
"""
<records>
<record index="1">a</record>
<record index="2">b</record>
<record index="3" foo="bar">c</record>
</records>
"""
我只想提取这个:
<record index="1">a</record>
<record index="2">b</record>
<record index="3" foo="bar">c</record>
我尝试了以下选项,但 none 成功了:
* def chk = foo//records/*
* def chk = foo//records/child::*
* def chk = foo//records/descendant::*
* print chk
打印后,我得到以下内容,如果我遗漏了什么或有任何其他方法可以为您提供建议it.Thank!
13:51:07.046 INFO - [print] {
"records": {
"record": [
{
"_": "a",
"@": {
"index": "1"
}
},
{
"_": "b",
"@": {
"index": "2"
}
},
{
"_": "c",
"@": {
"foo": "bar",
"index": "3"
}
}
]
}
}
编辑:如果您需要做的只是获取一组元素并将它们填充到另一个 XML 模板中,看起来一个简单的字符串替换就可以解决问题:
(我在这个答案的末尾留下了原来更长的答案以供参考)
* def foo =
"""
<records>
<record index="1">a</record>
<record index="2">b</record>
<record index="3" foo="bar">c</record>
</records>
"""
* replace foo.<records> = ''
* replace foo.</records> = ''
# you can do def bar = read('template.txt') in your case
* text bar =
"""
<after new="namespace">
@@foo@@
</after>
"""
* replace bar.@@foo@@ = foo
* xml bar = bar
* match bar ==
"""
<after new="namespace">
<record index="1">a</record>
<record index="2">b</record>
<record index="3" foo="bar">c</record>
</after>
"""
是的,空手道本身不支持 XML 节点列表,通常您不需要它。 XML 具有这种特性,您总是需要一个 "parent" 或 "wrapping" 元素。
正如您在上面看到的,您确实拥有所需的所有信息。我仍然不清楚您需要将哪种 XML 传递给下一个 API - 但无论如何,在空手道中有一种方法。这里有 2 个选项。首先,迭代数据并手动发出 XML:
* def foo =
"""
<records>
<record index="1">a</record>
<record index="2">b</record>
<record index="3" foo="bar">c</record>
</records>
"""
* json records = foo.records.record
* def temp = <bar></bar>
* def fun =
"""
function(r, i){
karate.set('temp', '/bar/record[' + (i+1) + ']', r._);
karate.set('temp', '/bar/record[' + (i+1) + ']/@index', r['@'].index);
}
"""
* eval karate.forEach(records, fun)
* match temp ==
"""
<bar>
<record index="1">a</record>
<record index="2">b</record>
<record index="3">c</record>
</bar>
"""
请注意,karate.forEach
仅在即将发布的 0.8.0 中可用,但您可以尝试 0.8.0.RC3
这是另一个有趣的选项,如果您需要做的只是更改 XML 父级,字符串替换就可以解决问题:
* replace foo.<records> = '<bar>'
* replace foo.</records> = '</bar>'
* xml bar = foo
* match bar ==
"""
<bar>
<record index="1">a</record>
<record index="2">b</record>
<record index="3" foo="bar">c</record>
</bar>
"""
我需要从一个 api 的响应中提取子元素,然后将其动态传递给下一个 api 请求。
假设我有以下 xml:
* def foo =
"""
<records>
<record index="1">a</record>
<record index="2">b</record>
<record index="3" foo="bar">c</record>
</records>
"""
我只想提取这个:
<record index="1">a</record>
<record index="2">b</record>
<record index="3" foo="bar">c</record>
我尝试了以下选项,但 none 成功了:
* def chk = foo//records/*
* def chk = foo//records/child::*
* def chk = foo//records/descendant::*
* print chk
打印后,我得到以下内容,如果我遗漏了什么或有任何其他方法可以为您提供建议it.Thank!
13:51:07.046 INFO - [print] {
"records": {
"record": [
{
"_": "a",
"@": {
"index": "1"
}
},
{
"_": "b",
"@": {
"index": "2"
}
},
{
"_": "c",
"@": {
"foo": "bar",
"index": "3"
}
}
]
}
}
编辑:如果您需要做的只是获取一组元素并将它们填充到另一个 XML 模板中,看起来一个简单的字符串替换就可以解决问题: (我在这个答案的末尾留下了原来更长的答案以供参考)
* def foo =
"""
<records>
<record index="1">a</record>
<record index="2">b</record>
<record index="3" foo="bar">c</record>
</records>
"""
* replace foo.<records> = ''
* replace foo.</records> = ''
# you can do def bar = read('template.txt') in your case
* text bar =
"""
<after new="namespace">
@@foo@@
</after>
"""
* replace bar.@@foo@@ = foo
* xml bar = bar
* match bar ==
"""
<after new="namespace">
<record index="1">a</record>
<record index="2">b</record>
<record index="3" foo="bar">c</record>
</after>
"""
是的,空手道本身不支持 XML 节点列表,通常您不需要它。 XML 具有这种特性,您总是需要一个 "parent" 或 "wrapping" 元素。
正如您在上面看到的,您确实拥有所需的所有信息。我仍然不清楚您需要将哪种 XML 传递给下一个 API - 但无论如何,在空手道中有一种方法。这里有 2 个选项。首先,迭代数据并手动发出 XML:
* def foo =
"""
<records>
<record index="1">a</record>
<record index="2">b</record>
<record index="3" foo="bar">c</record>
</records>
"""
* json records = foo.records.record
* def temp = <bar></bar>
* def fun =
"""
function(r, i){
karate.set('temp', '/bar/record[' + (i+1) + ']', r._);
karate.set('temp', '/bar/record[' + (i+1) + ']/@index', r['@'].index);
}
"""
* eval karate.forEach(records, fun)
* match temp ==
"""
<bar>
<record index="1">a</record>
<record index="2">b</record>
<record index="3">c</record>
</bar>
"""
请注意,karate.forEach
仅在即将发布的 0.8.0 中可用,但您可以尝试 0.8.0.RC3
这是另一个有趣的选项,如果您需要做的只是更改 XML 父级,字符串替换就可以解决问题:
* replace foo.<records> = '<bar>'
* replace foo.</records> = '</bar>'
* xml bar = foo
* match bar ==
"""
<bar>
<record index="1">a</record>
<record index="2">b</record>
<record index="3" foo="bar">c</record>
</bar>
"""