Skip to main content
Solved

How to update multiple attributes in an element in the XMLUpdater from an FME list?

  • January 17, 2020
  • 9 replies
  • 162 views

stephstedman
Participant
Forum|alt.badge.img+4

Hi everyone.

 

I am new to XML and am having some difficulties using the XMLUpdater and XQuery. My issue is around updating 3 attributes within an xml element from 3 attributes in an FME list to create multiple children. When I do this for a record which has say 2 items in the list it’s producing 9 children instead of 2, do I need to group my data somewhere in my XQuery?

 

I’ve attached a sample workbench and data.

 

I am reading an Excel document, then creating a list of all LCS_Codes and their measures per TAC_Code. I then want this list to form the children of a location element within my XML. So I’d hope to go from something like this:

 

Input table:

To this output XML text:

 

<tractionCurrentSection id="M58">

<location>

<part idEl="B077/MSBFA" startPos="0" endPos="149.302"></part>

<part idEl="B077/MSBLO" startPos="0" endPos="133.761"></part>

</location>

 

However I’m getting this:

 

<tractionCurrentSection id="M58">

<location>

<part idEl="B077/MSBFA" startPos="0" endPos="149.302"></part>

<part idEl="B077/MSBFA" startPos="0" endPos="133.761"></part>

<part idEl="B077/MSBFA" startPos="0" endPos="149.302"></part>

<part idEl="B077/MSBFA" startPos="0" endPos="133.761"></part>

<part idEl="B077/MSBLO" startPos="0" endPos="149.302"></part>

<part idEl="B077/MSBLO" startPos="0" endPos="133.761"></part>

<part idEl="B077/MSBLO" startPos="0" endPos="149.302"></part>

<part idEl="B077/MSBLO" startPos="0" endPos="133.761"></part>

</location>

</tractionCurrentSection>

 

I think the above is putting each part of the list to each part of the list, hence me having 9 children instead of 2 for the 3 attributes I’m updating. Is there a way I can tell the Xquery to group by the list entry instead?

 

XQuery:

 

<location>{

for $list in fme:get-list-attribute("_list{}.LCS_CODE") for $Startlist in fme:get-list-attribute("_list{}.Start Meterage 1") for $Endlist in fme:get-list-attribute("_list{}.End Meterage 1")

return <part idEl="{$list}" startPos="{$Startlist}" endPos="{$Endlist}" />

}</location>

 

A bit of a side second question…. In the example outputs from the customer I have the XML for the “part” element will just end /> (below), which is what I have put in the XMLUpdater (<part idEl="{$list}" startPos="{$Startlist}" endPos="{$Endlist}" />) but my output seems to be ></part> after my attributes, does this matter? I’ve been given a specific XSD to follow.

 

Example desired output

<location>

<part id=”D202/DEBLO” startPos=”0.00” endPos=”158.44”/>

<part id=”D203/DEBLO” startPos=”0.00” endPos=”130.77”/>

<part id=”D204/DEBLO” startPos=”54.98” endPos=”1097.19”/>

</location>

 

My current output

<location>

<part idEl="B077/MSBFA" startPos="0" endPos="149.302"></part>

<part idEl="B077/MSBLO" startPos="0" endPos="133.761"></part>

</location>

 

 

As a bit of background info this is part of a larger project where I have been given a rather massive XSD to map several of our GIS and Excel datasets to, this is just for one particular dataset. As I say I’m totally new to XML and have read through the W3 schools info to get a bit more acquainted but if anyone knows any other FME-XML specific resources it’s appreciated!

 

 

Thanks in advance!

Best answer by takashi

Hi @stephstedman, nested for statements would cause such duplication. Try this expression instead.

<location>{
    let $s := fme:get-list-attribute("_list{}.Start Meterage 1")
    let $e := fme:get-list-attribute("_list{}.End Meterage 1")
    for $code at $i in fme:get-list-attribute("_list{}.LCS_CODE")
    return
    <part idEl="{$code}" startPos="{$s[$i]}" endPos="{$e[$i]}" />
}</location>

 

Alternatively you can also generate your required result using just an XMLTempleter without using the XMLUpdater. This workspace example contains Plan B and Plan C that demonstrate the way.

tcs-to-xml-sample-2.fmwt (FME 2019.1.1)

Hope this helps.

View original
Did this help you find an answer to your question?

9 replies

takashi
Contributor
Forum|alt.badge.img+19
  • Contributor
  • Best Answer
  • January 17, 2020

Hi @stephstedman, nested for statements would cause such duplication. Try this expression instead.

<location>{
    let $s := fme:get-list-attribute("_list{}.Start Meterage 1")
    let $e := fme:get-list-attribute("_list{}.End Meterage 1")
    for $code at $i in fme:get-list-attribute("_list{}.LCS_CODE")
    return
    <part idEl="{$code}" startPos="{$s[$i]}" endPos="{$e[$i]}" />
}</location>

 

Alternatively you can also generate your required result using just an XMLTempleter without using the XMLUpdater. This workspace example contains Plan B and Plan C that demonstrate the way.

tcs-to-xml-sample-2.fmwt (FME 2019.1.1)

Hope this helps.


stephstedman
Participant
Forum|alt.badge.img+4
  • Author
  • Participant
  • January 20, 2020
takashi wrote:

Hi @stephstedman, nested for statements would cause such duplication. Try this expression instead.

<location>{
    let $s := fme:get-list-attribute("_list{}.Start Meterage 1")
    let $e := fme:get-list-attribute("_list{}.End Meterage 1")
    for $code at $i in fme:get-list-attribute("_list{}.LCS_CODE")
    return
    <part idEl="{$code}" startPos="{$s[$i]}" endPos="{$e[$i]}" />
}</location>

 

Alternatively you can also generate your required result using just an XMLTempleter without using the XMLUpdater. This workspace example contains Plan B and Plan C that demonstrate the way.

tcs-to-xml-sample-2.fmwt (FME 2019.1.1)

Hope this helps.

That's perfect, exactly what I needed it to do.  Thanks so much for your help @takashi


Forum|alt.badge.img+1
  • January 22, 2020

Hi @takashi, I have a similar question about the XMLUpdater. I want to get the following xml output:

<group id="X" category="line">

 

<section id="A">

 

<section id="B">

 

<section id="C">

 

</group>

I have created the following list using listbuilder grouping on ID and CATEGORY attributes: _list{}.CODE

 

In the XMLUpdater I have input the following parameters:

Group Update Features By: ID and CATEGORY

Update Type: Replace

XML Path: //group

Value Type: XML/XQuery

Value:

<group>{id="fme:get-attribute("ID")" category="fme:get-attribute("CATEGORY")"

 

for $code in fme:get-list-attribute("_list{}.CODE")

 

return

 

<section id="{$code}"/>

 

}</group>

 

However, this does not seem to be working. Can you please have a look and let me know if I am missing something?

Thanks,


takashi
Contributor
Forum|alt.badge.img+19
  • Contributor
  • January 22, 2020
aquamarine wrote:

Hi @takashi, I have a similar question about the XMLUpdater. I want to get the following xml output:

 <group id="X" category="line">

 

 <section id="A">

 

 <section id="B">

 

 <section id="C">

 

 </group>

I have created the following list using listbuilder grouping on ID and CATEGORY attributes: _list{}.CODE

 

In the XMLUpdater I have input the following parameters:

Group Update Features By: ID and CATEGORY

Update Type: Replace

XML Path: //group

Value Type: XML/XQuery

Value:

<group>{id="fme:get-attribute("ID")" category="fme:get-attribute("CATEGORY")"

 

 for $code in fme:get-list-attribute("_list{}.CODE")

 

 return

 

 <section id="{$code}"/>

 

}</group>

 

However, this does not seem to be working. Can you please have a look and let me know if I am missing something?

Thanks,

Hi @aquamarine, close, but wrong. Try this expression and take a closer look at what is different from your expression.

<group id="{fme:get-attribute("ID")}" category="{fme:get-attribute("CATEGORY")}">{
    for $code in fme:get-list-attribute("_list{}.CODE")
    return
    <section id="{$code}"/>
}</group>

Forum|alt.badge.img+1
  • January 22, 2020

HI Takashi

Thanks I see I had some issues with the syntax. I have now fixed that but I am unable to get the content in the XMLUpdater to replace that in the XMLTemplater. Perhaps I have the Update Type and/or XML Path incorrect?

This was the code in the original XMLTemplater:

<base xmlns:xsi=http://www.sss xmlns:rsml=http://www.sss xmlns=http://www.sss>

 

<group id="{fme:get-attribute("ID")}" category="{fme:get-attribute("CATEGORY")}" level="" name="" description="">

 

<section id="{fme:get-attribute("CODE")}" localStart="" category="" level="" name="" description="">

 

</section>

 

<group/>

 

</group>

 

</base>

Thanks


takashi
Contributor
Forum|alt.badge.img+19
  • Contributor
  • January 22, 2020
aquamarine wrote:

HI Takashi

Thanks I see I had some issues with the syntax. I have now fixed that but I am unable to get the content in the XMLUpdater to replace that in the XMLTemplater. Perhaps I have the Update Type and/or XML Path incorrect?

This was the code in the original XMLTemplater:

<base xmlns:xsi=http://www.sss xmlns:rsml=http://www.sss xmlns=http://www.sss>

 

<group id="{fme:get-attribute("ID")}" category="{fme:get-attribute("CATEGORY")}" level="" name="" description="">

 

<section id="{fme:get-attribute("CODE")}" localStart="" category="" level="" name="" description="">

 

</section>

 

<group/>

 

</group>

 

</base>

Thanks

Unfortunately the template expression causes an error so cannot test the subsequent XMLUpdater. Please post a correct expression.


Forum|alt.badge.img+1
  • January 22, 2020
takashi wrote:

Unfortunately the template expression causes an error so cannot test the subsequent XMLUpdater. Please post a correct expression.

actually the XMLupdater does work now. I didn't fix the syntax properly the first time.

  • August 31, 2021
takashi wrote:

Hi @stephstedman, nested for statements would cause such duplication. Try this expression instead.

<location>{
    let $s := fme:get-list-attribute("_list{}.Start Meterage 1")
    let $e := fme:get-list-attribute("_list{}.End Meterage 1")
    for $code at $i in fme:get-list-attribute("_list{}.LCS_CODE")
    return
    <part idEl="{$code}" startPos="{$s[$i]}" endPos="{$e[$i]}" />
}</location>

 

Alternatively you can also generate your required result using just an XMLTempleter without using the XMLUpdater. This workspace example contains Plan B and Plan C that demonstrate the way.

tcs-to-xml-sample-2.fmwt (FME 2019.1.1)

Hope this helps.

Hi, Can you share the tcs-to-xml-sample-2.fmwt as I am trying to do something similar. Thx


kailinatsafe
Safer
Forum|alt.badge.img+19
sdave wrote:

Hi, Can you share the tcs-to-xml-sample-2.fmwt as I am trying to do something similar. Thx

Hello @sdave​ , tcs-to-xml-sample-2.fmwt should be available in Takashi's comment now. Best, Kailin.


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