Skip to main content

My features have an attribute containing an XML document and a list attribute. As an example, imagine the XML attribute containing this document:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <foo bar="aaa"/>
  <baz>
    <foo bar="bbb"/>
    <foo bar="ccc"/>
  </baz>
</root>

And the list attributes containing these values:

list{0}.ident = "aaa"
list{0}.value = "xxx"
list{1}.ident = "bbb"
list{1}.value = "yyy"
list{2}.ident = "ccc"
list{2}.value = "zzz"

What I want to achieve is to update the XML attribute so that it contains this modified XML document:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <foo bar="xxx"/>
  <baz>
    <foo bar="yyy"/>
    <foo bar="zzz"/>
  </baz>
</root>

I think this should be easily doable using the XMLXQueryUpdater in conjunction with the FME XQuery functions, but I just don't get it right...

Thanks for your help,

David

Hi @dfundter, it would be a little advanced XQuery expression.

let $m := <map>{
    let $values := fme:get-list-attribute("list{}.value")
    for $key at $i in fme:get-list-attribute("list{}.ident")
    return <item key="{$key}" value="{$valuesi$i]}"/>
}</map>
for $foo in //foo
return replace value of node $foo/@bar with $m/itemc@key = $foo/@bar]/@value

Hi @dfundter, it would be a little advanced XQuery expression.

let $m := <map>{
    let $values := fme:get-list-attribute("list{}.value")
    for $key at $i in fme:get-list-attribute("list{}.ident")
    return <item key="{$key}" value="{$valuesi$i]}"/>
}</map>
for $foo in //foo
return replace value of node $foo/@bar with $m/itemc@key = $foo/@bar]/@value
Thanks @takashi! The intermediate XML node didn't come to my mind. I was stuck trying to inline loop through the list...

 


Hi @dfundter, it would be a little advanced XQuery expression.

let $m := <map>{
    let $values := fme:get-list-attribute("list{}.value")
    for $key at $i in fme:get-list-attribute("list{}.ident")
    return <item key="{$key}" value="{$valuesi$i]}"/>
}</map>
for $foo in //foo
return replace value of node $foo/@bar with $m/itemc@key = $foo/@bar]/@value
Another solution. This may be simpler.

 

let $idents := fme:get-list-attribute('list{}.ident')
let $values := fme:get-list-attribute('list{}.value')
for $foo in //foo
return replace value of node $foo/@bar with $values/index-of($idents, $foo/@bar)]

 


Another solution. This may be simpler.

 

let $idents := fme:get-list-attribute('list{}.ident')
let $values := fme:get-list-attribute('list{}.value')
for $foo in //foo
return replace value of node $foo/@bar with $valuesoindex-of($idents, $foo/@bar)]

 

Very nice!

Reply