Solved

How to handle missing attributes in lists with xquery

  • 23 November 2018
  • 2 replies
  • 10 views

Badge +10

Building an xml with XMLTemplater transformer, some attributes are lists where some element may not exist.

For example, I have contact information for 3 organizations and some may not have an individual name:

contact{0}.CI_ResponsibleParty.organisationName.CharacterString

 

contact{0}.CI_ResponsibleParty.individualName.CharacterString

 

contact{0}.CI_ResponsibleParty.contactInfo.CI_Contact.phone.CI_Telephone.voice.CharacterString

 

contact{1}.CI_ResponsibleParty.organisationName.CharacterString

 

contact{1}.CI_ResponsibleParty.contactInfo.CI_Contact.phone.CI_Telephone.voice.CharacterString

 

contact{2}.CI_ResponsibleParty.organisationName.CharacterString

 

contact{2}.CI_ResponsibleParty.individualName.CharacterString

 

contact{2}.CI_ResponsibleParty.contactInfo.CI_Contact.phone.CI_Telephone.voice.CharacterString

 

To populate the xml with a contact block for each organization I do this:

{

 

let $individualName := fme:get-list-attribute("contact{}.CI_ResponsibleParty.individualName.CharacterString")

 

let $voice := fme:get-list-attribute("contact{}.CI_ResponsibleParty.contactInfo.CI_Contact.phone.CI_Telephone.voice.CharacterString")

 

for $organisationName at $i in fme:get-list-attribute("contact{}.CI_ResponsibleParty.organisationName.CharacterString")

 

return

 

<gmd:contact>

 

<gmd:CI_ResponsibleParty>

 

<gmd:individualName>

 

<gco:CharacterString>{$individualName[$i]}</gco:CharacterString>

 

</gmd:individualName>

 

<gmd:organisationName>

 

<gco:CharacterString>{$organizationName[$i]}</gco:CharacterString>

 

</gmd:organisationName>

 

<gmd:contactInfo>

 

<gmd:CI_Contact>

 

<gmd:phone>

 

<gmd:CI_Telephone>

 

<gmd:voice>

 

<gco:CharacterString>{$voice[$i]}</gco:CharacterString>

 

</gmd:voice>

 

</gmd:CI_Telephone>

 

</gmd:phone>

 

</gmd:CI_Contact>

 

</gmd:contactInfo>

 

</gmd:CI_ResponsibleParty>

 

</gmd:contact>

 

}

But $individualName is empty if any element in the list is missing so no organization gets the contact\\CI_ResponsibleParty\\individualName\\CharacterString node populated.

Any idea?

There's a NullAttributeMapper transformer to map missing attributes but I have many lists with multiple elements (some of them are nested lists) so I'll need quite a bunch of transformers. There must be some other way.

icon

Best answer by takashi 23 November 2018, 21:33

View original

2 replies

Userlevel 2
Badge +17

You can treat individual list elements as regular attributes and get their values with the "fme:get-attribute" function. Just be aware that index of elements in an FME list attribute is 0-based, whereas index of elements in an XQuery sequence is 1-based.

Example:

{
for $oName at $i in fme:get-list-attribute("contact{}.CI_ResponsibleParty.organisationName.CharacterString")
let $prefix := 'contact{'||{$i - 1}||'}.CI_ResponsibleParty.'
let $iName := fme:get-attribute($prefix||'individualName.CharacterString')
let $voice := fme:get-attribute($prefix||'contactInfo.CI_Contact.phone.CI_Telephone.voice.CharacterString')
return
<gmd:contact>
  <gmd:CI_ResponsibleParty>
    <gmd:individualName>
      <gco:CharacterString>{$iName}</gco:CharacterString>
    </gmd:individualName>
    <gmd:organisationName>
      <gco:CharacterString>{$oName}</gco:CharacterString>
    </gmd:organisationName>
    <gmd:contactInfo>
      <gmd:CI_Contact>
        <gmd:phone>
          <gmd:CI_Telephone>
            <gmd:voice>
              <gco:CharacterString>{$voice}</gco:CharacterString>
            </gmd:voice>
          </gmd:CI_Telephone>
        </gmd:phone>
      </gmd:CI_Contact>
    </gmd:contactInfo>
  </gmd:CI_ResponsibleParty>
</gmd:contact>
}
Badge +10

Thank you @takashi! Your posts are always helpful.

Reply