Varsha --
I'm happy to see you're using XDM and XDM elaboration!
Here are a couple possible approaches for the issue you describe. The first, using alternate domains, is somewhat specialized, but is worth knowing about. The second, using xpath expressions, is much more general. I often start with the xpath approach.
Hope this helps.
I'm assuming you started with a test case something like this, and found that the "keyword elaboration" of the empty 'exists' tag was an empty string which was rejected by the parser for the boolean domain in your recordset.
{def test = "
<items>
<item>
<title>ABC</title>
<exists/>
</item>
<item>
<title>XYZ</title>
</item>
</items>"
}
{def xml =
{build-xml preserve-whitespace? = false, test}.root
}
{value
|| define the transformation
def e =
{xml-elaboration
{"items" {...:RecordData}:RecordSet
{RecordSet
|| explicit structure, not declared in source
{RecordFields
{RecordField "title", domain = String},
{RecordField "exists", domain = bool}},
|| records corresponding to items
{splice ...}}}
|| contents will be treated as keywords
{"item" RecordData}
|| treat these tags as keywords
{"title" XmlKeywordPrototype}
{"exists" XmlKeywordPrototype}
|| other tags will be ignored
}
|| transform the source
def rs = {e.elaborate xml} asa RecordSet
|| display the data
{RecordGrid record-source = rs,
width = 10cm, height = 4cm,
{RecordGridColumn "title"},
{RecordGridColumn "exists"}}
}
That specific issue could be addressed by using a specialized domain that parses any string as true, so the presence or absence of the tag would control the value. Then, using 'domain = {SpecialBoolDomain }' instead of 'domain = bool' would give the result you want.
{define-class public SpecialBoolDomain {inherits StandardBoolDomain}
{constructor public {default ...}
{construct-super {splice ...}}
}
{method public {parse x:String}:any
{return true}
}
}
But that approach is specialized, and couples the recordset field descriptors with the data exchange format. A more general approach is to use xpath expressions to obtain appropriate values from each element. When the argument pattern in an 'elaborate-xml' clause has an XDMElement type, that object is available to compute the result. The the elaboration could be defined like this.
|| define the transformation
def e =
{xml-elaboration
{"items" {...:RecordData}:RecordSet
{RecordSet
|| explicit structure, not declared in source
{RecordFields
{RecordField "title", domain = String},
{RecordField "exists", domain = bool}},
|| records corresponding to items
{splice ...}}}
|| process contents using xpath
{"item" {x:XDMElement}:RecordData
def title = {x.search "title"}.as-String
def exists = {x.search "exists"}.as-bool
{RecordData
title = title,
exists = exists}}
}
By the way, you can use xpath expressions with any XDM object, regardless of whether you're using elaborate-xml.