Skip to main content
Solved

How to handle missing attributes in lists with xquery

  • November 23, 2018
  • 2 replies
  • 35 views

dms2
Contributor
Forum|alt.badge.img+11
  • Contributor

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.

Best answer by takashi

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>
}
View original
Did this help you find an answer to your question?

2 replies

takashi
Influencer
  • Best Answer
  • November 23, 2018

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>
}

dms2
Contributor
Forum|alt.badge.img+11
  • Author
  • Contributor
  • November 26, 2018

Thank you @takashi! Your posts are always helpful.


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings