Parsing XML complex response

Hi

I need to test a backend services that return a big complex xml data from wich I need to retrieve some information in order to dynamically creates HTTP GET request (requests that I actually want to test). Is there any library to parse XML response and then do some xpath search in the xml document ? Something similar to the parseHTML() method. I haven’t tried yet but would the parseHTML() also works for non HTML xml files ? HTML is xml but I don’t know if the implementation of this method really requires HTML or would be fine with every xml data ?
Thanks in advance for any help.

Hi Brice,

Thanks for reaching out, I’ll try my best to support you.

Regarding your testing strategy, to avoid any misunderstanding or wrong assumption, would you be open to share an anonymized version of your script?

Regarding parsing XML specifically, although I’m not too familiar with XML myself, I’m pretty sure you’re right, and it should be possible to parse native XML using an HTML parser, considering one is a subset of the other. To verify it, I checked out and experimented with our implementation of the parseHTML method exposed by the k6/html module. It appears possible to parse custom XML documents using it, indeed. The parseHTML function uses the goquery Go library under the hood. At first sight, I can’t see anything making it specific to HTML. The function itself returns a Selection object from this library, and wraps a subset of its API. You should be able to work out something using it. Here’s a super basic example showing that parseHTML doesn’t complain when sent some super basic XML.

import http from "k6/http";
import { parseHTML } from "k6/html";

export default function() {
    let res = http.get('https://www.w3schools.com/xml/note.asp')
    let sel = parseHTML(res.body);
    console.log(sel.text());    
}

If you use VSCode, and haven’t done so already, this guide will set you up with Intellisense, and you should get autocompletion, hopefully helping you to figure out how to manipulate your XML documents from there. If you’re familiar with Go, you can also check out the public API the module exposes, the method you’ll find there are exposed (lowercased) to the Selection instance returned by parseHTML in the context of the script.

Let me know if that helps,
Cheers

Thanks for your help, I’ll try with the parseHTML().

1 Like

Hello
I tried the parseHTML() method. However it seems that this method doesn’t supports searching for element within an xml namespace. I tried to search for Elements in the Selection using the find() method and the Element that I need to search is prefixed with a namespace and this doesn’t seems to work. Here below an example:

// Working example without xml namespace
let content = `
<Capabilities>
    <Identifier id="term-1">Value term 1</Identifier>
    <Identifier id="term-2">Value term 2</Identifier>
</Capabilities>
`
let sel = parseHTML(content).find('Identifier')
let el1 = sel.get(0)
let el2 = sel.get(1)

console.log(el1.nodeName())
console.log(el1.id())
console.log(el1.textContent())

console.log(el2.nodeName())
console.log(el2.id())
console.log(el2.textContent())

// Non working exemple, sel is empty
content = `
<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1">
    <ows:Identifier id="term-1">Value term 1</ows:Identifier>
    <ows:Identifier id="term-2">Value term 2</ows:Identifier>
</Capabilities>
`
sel = parseHTML(content).find('ows:Identifier')
el1 = sel.get(0)
el2 = sel.get(1)

console.log(el1.nodeName())
console.log(el1.id())
console.log(el1.textContent())

console.log(el2.nodeName())
console.log(el2.id())
console.log(el2.textContent())

I finally found the way to search for Element within a namespace (see jQuery selecting a selector with namespaced element - Stack Overflow)
The xml prefix must be followed by \\: and not by :.

content = `
<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1">
    <ows:Identifier id="term-1">Value term 1</ows:Identifier>
    <ows:Identifier id="term-2">Value term 2</ows:Identifier>
</Capabilities>
`
sel = parseHTML(content).find('ows\\:Identifier')
el1 = sel.get(0)
el2 = sel.get(1)

console.log(el1.nodeName())
console.log(el1.id())
console.log(el1.textContent())

console.log(el2.nodeName())
console.log(el2.id())
console.log(el2.textContent())
1 Like