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
Influencer
  • 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
Influencer
  • 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!

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