Skip to main content
Question

XML Templater empty subtemplate

  • September 12, 2017
  • 2 replies
  • 30 views

jdh
Contributor
Forum|alt.badge.img+37
  • Contributor
  • 2002 replies

I am looking for a way to have a "default value"  if there is no data in a subtemplate.

 

 

Consider the house, village example from the help documentation.  If we have multiple villages with an id, and multiple houses with a village_id,  we can set the Root template to 

<village>
<name>{fme:get-attribute("name")}</name>
<population>{fme:get-attribute("population")}</population>
<houses>
{fme:process-features("HOUSE", "village_id", fme:get-attribute("id"))}
</houses>
</village>

and the correct houses will be associated with the correct village.

 

and you could end up with an output like

 

<village>
<name>Anytown, USA</name>
<population>2568</population>
<houses>
<house>
<address>123 Main Street</address>
<owner>John Doe</owner>
</house>
<house>
<address>324 Main Street</address>
<owner>Jane Doe</owner>
</house>
</houses>
</village>

However if there are no houses for a specific village, the result is

<village>
<name>Anytown, USA</name>
<population>2568</population>
<houses>

 </houses>
</village>
Instead of empty space, I would like to specify an alternate value.

Something like

<village>
<name>Anytown, USA</name>
<population>2568</population>
<houses>No houses available</houses>
</village>

In my data the root feature (village) has no information as to the number of subfeatures (houses) associated with it, so I can't simply use a conditional like

<houses>
{ if( (fme:get-attribute("housecount") eq "0") )
then {fme:process-features("HOUSE", "village_id", fme:get-attribute("id"))}
else "No houses available" 
}
</houses>

Any thoughts?  I have several thousand root features and several hundred thousand subfeatures so I would like to avoid using a featureMerger on the data prior to the XMLTemplater if at all possible.

This post is closed to further activity.
It may be an old question, an answered question, an implemented idea, or a notification-only post.
Please check post dates before relying on any information in a question or answer.
For follow-up or related questions, please post a new question or idea.
If there is a genuine update to be made, please contact us and request that the post is reopened.

2 replies

takashi
Celebrity
  • 7843 replies
  • September 12, 2017

Hi @jdh, this expression might help you.

<village>
<name>{fme:get-attribute("name")}</name>
<population>{fme:get-attribute("population")}</population>
{
let $houses := <houses>{
    fme:process-features("HOUSE", "village_id", fme:get-attribute("id"))
}</houses>
return if (0 < fn:count($houses/house))
then $houses
else <houses>No houses available</houses> 
}
</village>

takashi
Celebrity
  • 7843 replies
  • September 13, 2017

Hi @jdh, this expression might help you.

<village>
<name>{fme:get-attribute("name")}</name>
<population>{fme:get-attribute("population")}</population>
{
let $houses := <houses>{
    fme:process-features("HOUSE", "village_id", fme:get-attribute("id"))
}</houses>
return if (0 < fn:count($houses/house))
then $houses
else <houses>No houses available</houses> 
}
</village>
This expression is also available.

 

<village>
<name>{fme:get-attribute("name")}</name>
<population>{fme:get-attribute("population")}</population>
<houses>{
let $houses := {
    fme:process-features("HOUSE", "village_id", fme:get-attribute("id"))
}
return
if (0 < fn:count($houses)) then $houses else "No houses available"
}</houses>
</village>
For what it's worth, in my experiences, XMLTemplater with a sub template worked not so efficient in many cases. Depending on the conditions, processing a list attribute within a single root expression could be faster. e.g.

0684Q00000ArMhGQAV.png

<village>
<name>{fme:get-attribute("name")}</name>
<population>{fme:get-attribute("population")}</population>
<houses>{
let $houses := {
    let $owners := fme:get-list-attribute("_list{}.owner")
    for $address at $i in fme:get-list-attribute("_list{}.address")
    return
    <house>
        <address>{$address}</address>
        <owner>{$owners[$i]}</owner>
    </house>
}
return
if (0 < fn:count($houses)) then $houses else "No houses available"
}</houses>
</village><br>