Skip to main content
Solved

How to update XML attribute with content of list attribute


Forum|alt.badge.img

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

Best answer by takashi

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="{$values[$i]}"/>
}</map>
for $foo in //foo
return replace value of node $foo/@bar with $m/item[@key = $foo/@bar]/@value
View original
Did this help you find an answer to your question?

4 replies

takashi
Evangelist
  • Best Answer
  • July 19, 2018

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="{$values[$i]}"/>
}</map>
for $foo in //foo
return replace value of node $foo/@bar with $m/item[@key = $foo/@bar]/@value

Forum|alt.badge.img
  • Author
  • July 20, 2018
takashi wrote:

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="{$values[$i]}"/>
}</map>
for $foo in //foo
return replace value of node $foo/@bar with $m/item[@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...

 


takashi
Evangelist
  • July 20, 2018
takashi wrote:

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="{$values[$i]}"/>
}</map>
for $foo in //foo
return replace value of node $foo/@bar with $m/item[@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)]

 


Forum|alt.badge.img
  • Author
  • July 20, 2018
takashi wrote:
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)]

 

Very nice!

Reply


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