问题
I am having troubles with XML matching, which appears to be working a bit differently from JSON.
I found this code snippet
* def xml = <foo><bar>baz</bar></foo>
* set xml/foo/bar = <hello>world</hello>
* match xml == <foo><bar><hello>world</hello></bar></foo>
But with this, I cannot specify that I'm using a template, and that <hello>world</hello>
may be present more than once.
Scenario XML 1 is failing, while the others are working.
Scenario: Scenario XML 1
* def response = <response><foo><bar><msg name="Hello"/><msg name="World"/></bar><bar><msg name="Hello"/><msg name="World"/></bar></foo></response>
* def bar = <bar><msg name="Hello"/><msg name="World"/></bar>
* def foo = <response><foo>#[](bar)</foo></response>
* print foo
* print response
* match response == foo
Scenario: Scenario XML 2
* def response = <response><foo><bar><msg name="Hello"/><msg name="World"/></bar></foo></response>
* def bar = <bar><msg name="Hello"/><msg name="World"/></bar>
* def foo = <response><foo>#(bar)</foo></response>
* print foo
* print response
* match response == foo
Scenario: Scenario JSON 1
* def response = {"response": {"foo": [{"bar": [{"msg": "Hello World"},{"msg": "Hello World"}]}, {"bar": [{"msg": "Hello World"},{"msg": "Hello World"}]}]}}
* def bar = {"bar": [{"msg": "Hello World"},{"msg": "Hello World"}]}
* def foo = {"response": {"foo": #[](bar)}}
* print foo
* print response
* match response == foo
Scenario: Scenario JSON 2
* def response = {"response": {"foo": {"bar": [{"msg": "Hello World"},{"msg": "Hello World"}]}}}
* def bar = {"bar": [{"msg": "Hello World"},{"msg": "Hello World"}]}
* def foo = {"response": {"foo": #(bar)}}
* print foo
* print response
* match response == foo
How can I have Scenario XML 1 working?
回答1:
I admit this can be considered a gap. The fact that XML repeated elements are so different from JSON doesn't help. The best I could do is this:
* def response = <foo><bar><msg name="Hello"/><msg name="World"/></bar><bar><msg name="Hello"/><msg name="World"/></bar></foo>
* def bar = <bar><msg name="Hello"/><msg name="World"/></bar>
* def foo = <foo>#ignore</foo>
* match response == foo
* match /foo/bar/msg[1]/@name == ['Hello', 'Hello']
* def names = $response/foo/bar/msg[1]/@name
* match each names == 'Hello'
Feel free to submit a feature request and suggest based on your experience with JSON what the ideal syntax should look like.
EDIT: thought about it a little and realized because of how Karate converts XML into JSON-like data internally, you have this option.
* json response = <response><foo><bar><msg name="Hello"/><msg name="World"/></bar><bar><msg name="Hello"/><msg name="World"/></bar></foo></response>
* json bar = <bar><msg name="Hello"/><msg name="World"/></bar>
* match each response.response.foo.bar == bar.bar
* match response == { response: { foo: { bar: '#[] bar.bar' } } }
I know it may be a little hard to understand, but will work :) I was looking at the code right now, and because of how involved the JSON matching is - it is unlikely to get re-factored to support XML repeated elements.
EDIT2: actually we made a fix now so this should be possible also:
* match response == <response><foo><bar>#[] bar.bar</bar></foo></response>
https://github.com/intuit/karate/issues/653
来源:https://stackoverflow.com/questions/54239617/xml-trouble-with-fuzzy-matching