How to handle xml inside foreach? --> incompatible types: expected 'xml', found '(xml|string)'

170 views Asked by At

can someone help me understand how xml elements work with respect to a foreach statement?

The sample code below shows two different ways to access the xml elements "Child". First, directly accessing all "Child" (line 3) and second accessing only the "Child" of a specific "Person" inside a foreach loop (line 5).

  1. Why do I get the compiling error?
  2. What do I need to do to access all "Child" elements for a specific "Person" while iterating over all "Person"?

test.bal:

function foo(xml input) returns boolean{
  xml listOfPersons = input/<Person>;
  xml listOfChildren = input/<Person>/<Child>;
  foreach var person in listOfPersons{
    xml childrenOfSinglePerson = person/<Child>;
  }
}

Compile result:

Compiling source
        test.bal
error: .::test.bal:5:20: incompatible types: expected 'xml', found '(xml|string)'

I'm using Ballerina 1.2

1

There are 1 answers

0
Dhananjaya On BEST ANSWER
  1. This error is due to a bug in xml iterator type checking. https://github.com/ballerina-platform/ballerina-lang/issues/24562

  2. During the execution of the program iterator will not return string results hence you can safely cast the person to xml or you a type guard (type test) as demonstrated below.

function foo(xml input) returns boolean {
  xml listOfPersons = input/<Person>;
  xml listOfChildren = input/<Person>/<Child>;
  foreach var person in listOfPersons {
    if (person is xml) { // Workaround to only consider xml
        xml childrenOfSinglePerson = person/<Child>;
        return true;
    }
  }
}

Alternatively you can also you .forEach method on xml value.

listOfPersons.forEach(function (xml person) { xml c = person/<Child>; io:println(c); });