Skip to content
CodeKruPro

XML Product Validation

50/62

XML Product Validation

The /xml/products endpoint returns products in XML (with a flat structure — no nested objects):

<products>
  <product><id>1</id><name>Laptop Pro</name><price>1299.99</price><category>electronics</category>...</product>
</products>

Task: Extract the first product's name and category from the XML response.

Expected output:

Product: Laptop Pro
Category: electronics

About this lesson

REST Assured: parse an XML response and read product fields with XmlPath

Learn REST AssuredAdvancedXML Responses

How it works

The /xml/products endpoint lists five products, one <product> element each, with id, name, price, category and inStock children. Compare that with the JSON product at /products/1, where category is an object holding its own id and name. In this XML feed the category is a plain text element. The structures look similar but are not interchangeable, and a path copied from a JSON test will not find anything here.

Every XML value is text until you say otherwise. get() and getString() on the price both return the String "1299.99", and get() on a stock flag returns "false" as a String too. The typed getters convert: getDouble() yields a Double of 1299.99, and getBoolean() on the fourth product's flag yields false. Interesting detail for anyone switching formats: JsonPath returns a Float for that same price in JSON, while XmlPath gives a Double when asked.

Validation in XML is mostly about reaching the right element and comparing it as the right type. GPath closures make that easier on a list: findAll with a condition on category filters the products, and adding .name after it collects just their names, which getList() returns as a Java list.

About the assignment

Request the XML product catalogue and print the first product's name and its category, each after a label.

What you will do

  1. Send a GET for /xml/products and call xmlPath() on the response.
  2. Read the first product's name with getString() and the root-first path shown in the starter comment.
  3. Read its category from the same element. It is a direct child that holds text, so the path ends at category with nothing after it.
  4. Print a Product: line with the name and a Category: line with the category.

Common mistakes

  • Carrying over the JSON path

    In JSON you would write category.name. Here that path points at an element that does not exist, and XmlPath returns an empty string instead of failing, so the output simply shows a blank category.

  • Casting get() to a number

    Assigning the result of get() on the price to a Double variable compiles, then throws ClassCastException at runtime because the value is a String. Call getDouble() when you need a number.

  • Relying on element order

    Index zero is the first product today. If the feed is ever sorted differently, the test reads another item. For checks that matter, locate the element by content with a find closure, then read the field you want.

In a real test suite

XML product and pricing feeds are common in retail integrations, and tests against them usually check a handful of business rules: prices parse as positive numbers, every product has a category, flags are real booleans. A JUnit 5 test can read the whole name list with getList() and assert on it with Hamcrest hasItems(), then spot-check one element by content.

To try one of these calls on any API endpoint without a task, open the Online Selenium Java Compiler (REST Assured is included).

Starter code

The editor above opens with this code. Fill in the TODO lines, then run and submit it.

Main.java
import io.restassured.RestAssured;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;
import io.restassured.path.xml.XmlPath;
import static io.restassured.RestAssured.*;

public class Main {
    public static void main(String[] args) {
        RestAssured.baseURI = "https://testkru.com/api";

        // TODO: GET /xml/products
        // TODO: Extract first product's name and category using XmlPath
        // Path: "products.product[0].name" and "products.product[0].category"
    }
}