BruceyBandit
BruceyBandit

Reputation: 4324

How to retrieve all instances of an attribute from an xml

I have a piece of code below where it looks for an attribute known as 'ExtranetContract'within the xml and performs an assertion to check that the attribute does exist and that its value equals 'true'.

def DailyContracts = xml.'soap:Body'
                .TestResponse
                .TestContractType
                .DailyContracts

def ContractType = DailyContracts.findAll { it.@Type == "C"}

def ExtranetContract = ContractType.DailyContract[0].@ExtranetContract

assert ExtranetContract.size() > 0 && ExtranetContract.every { it == 'true' } 

Notice the line: def ExtranetContract = ContractType.DailyContract[0].@ExtranetContract. The [0] represents the first instance of DailyContract(where the contact type equals 'C'.

I am not sure if it will work if I have two or more extranet contracts under contract type 'C' (I have't got an example to test myself but I have created a dummy xml to show an example on where the above line of code may not work effectively in checking all extranet contracts attributes

<Contracts>
 <DailyContracts Type="S">
    <DailyContract Type="TEST" Code="xxx">
       <Name>Extranet</Name>
    </DailyContract>
    </DailyContracts>
 <DailyContracts Type="C">
  <DailyContract Type="TEST" Code="xxx" ExtranetContract="true">
    <Name>Test Hotel 1</Name>
  </DailyContract>
    <DailyContract Type="TEST" Code="xxx" ExtranetContract="true">
    <Name>Test Hotel 2</Name>
  </DailyContract>
 </DailyContracts>
</Contracts>

My question is simply how can I replace the [0] so that it checks all extranet contracts? I tried replacing [0] with .findAll and 'collect' but no luck.

Upvotes: 0

Views: 55

Answers (2)

Opal
Opal

Reputation: 84756

The following line:

def ExtranetContract = ContractType.DailyContract[0].@ExtranetContract

gives you an instance of FilteredNodeChildren. Since this class is an instance of Iterable you can use spread operator:

import groovy.util.XmlSlurper

def input = '''<Contracts>
 <DailyContracts Type="S">
    <DailyContract Type="FIT" Code="xxx" Start="2017-08-15" Days="7">
       <Name>Extranet</Name>
    </DailyContract>
    </DailyContracts>
 <DailyContracts Type="C">
  <DailyContract Type="FIT" Code="xxx" Start="2017-08-15" Days="7" ExtranetContract="true">
    <Name>Melia Costa Del Sol Extranet</Name>
  </DailyContract>
    <DailyContract Type="FIT" Code="xxx" Start="2017-08-15" Days="7" ExtranetContract="true">
    <Name>Melia Costa Del Sol Extranet 2</Name>
  </DailyContract>
 </DailyContracts>
</Contracts>'''

def slurped = new XmlSlurper().parseText(input)

def ContractType = slurped.DailyContracts.findAll { it.@Type == "C"}

def ExtranetContract = ContractType.DailyContract*.@ExtranetContract

assert ExtranetContract.size() == 2 && ExtranetContract.every { it == 'true' } 

Upvotes: 0

Rao
Rao

Reputation: 21359

You do it as below:

//Pass the response as String to parseText method
def xml = new XmlSlurper().parseText(response)
//Get the Daily Contracts of type C
def contracts = xml.'**'.findAll { it.name() == 'DailyContracts' && it.@Type == 'C'}
//Get the ExtranetContract values
def eCon = contracts.DailyContract*.@ExtranetContract
assert eCon instanceof List
assert !(false in eCon)

You can try it quickly online Demo

Upvotes: 1

Related Questions