Solved

XMLUpdater - Conditional XQuery to keep existing element values if update attributes are empty

  • 10 April 2018
  • 3 replies
  • 14 views

Badge +10

I have a working workspace to update metadata documents based on information from different sources like JSON files, file geodatabases, and so on.

Now I've realized that some of these sources may not have values for some of the metadata elements I'm updating.

For example, a JSON file may have a key-value pair: "_xmin": ""

To avoid updating elements with an empty value I'm using conditional xqueries in my XMLUpdater transformer, but I don't know what I should write in the 'else' statement. If I leave it empty, element values are updated with and empty value and I don't want that.

For the above example:

{if (not(fme:get-attribute("_minx") eq "")) then (fme:get-attribute("_minx")) else (*keep existing values!*)}

icon

Best answer by takashi 11 April 2018, 01:11

View original

3 replies

Userlevel 2
Badge +17

Hi @dms2, a possible way is to extract the original values from the source XML document as feature attributes (e.g. _original_minx, _original_maxx etc.), merge them to the Update feature, then use them in the expressions. e.g.

if (fme:get-attribute('_minx') ne '') then fme:get-attribute('_minx') else fme:get-attribute('_original_minx')

Alternatively, the XMLXQueryUpdater can also be used more flexibly, if you merge the new values (_minx, _maxx etc.) to the feature which has the XML document. Assuming that the feature has an attribute called "response" which stores this XML document, the following setting is possible.

<?xml version="1.0"?>
<root>
    <minx>0</minx>
    <maxx>100</maxx>
</root>

XQuery Expression:

let $minx := xs:string(fme:get-attribute("_minx"))
let $maxx := xs:string(fme:get-attribute("_maxx"))
return {
    if ($minx ne '') then replace value of node /root/minx with $minx else (),
    if ($maxx ne '') then replace value of node /root/maxx with $maxx else ()
}

0684Q00000ArLPZQA3.png

Userlevel 2
Badge +17

Hi @dms2, a possible way is to extract the original values from the source XML document as feature attributes (e.g. _original_minx, _original_maxx etc.), merge them to the Update feature, then use them in the expressions. e.g.

if (fme:get-attribute('_minx') ne '') then fme:get-attribute('_minx') else fme:get-attribute('_original_minx')

Alternatively, the XMLXQueryUpdater can also be used more flexibly, if you merge the new values (_minx, _maxx etc.) to the feature which has the XML document. Assuming that the feature has an attribute called "response" which stores this XML document, the following setting is possible.

<?xml version="1.0"?>
<root>
    <minx>0</minx>
    <maxx>100</maxx>
</root>

XQuery Expression:

let $minx := xs:string(fme:get-attribute("_minx"))
let $maxx := xs:string(fme:get-attribute("_maxx"))
return {
    if ($minx ne '') then replace value of node /root/minx with $minx else (),
    if ($maxx ne '') then replace value of node /root/maxx with $maxx else ()
}

0684Q00000ArLPZQA3.png

Note that namespace declarations will be required in XQuery expressions if the source XML contains namespaces. See also this Q&A;: Add zeros in real numbers

 

[Addition] This is an example if the XML elements belong to a namespace.

 

Source XML:

 

<?xml version="1.0"?>
<k:root xmlns:k="http://www.foobar.com/xml/k">
    <k:minx>0</k:minx>
    <k:maxx>100</k:maxx>
</k:root>
XQuery Expression:

 

declare namespace k="http://www.foobar.com/xml/k";
let $minx := xs:string(fme:get-attribute("_minx"))
let $maxx := xs:string(fme:get-attribute("_maxx"))
return {
    if ($minx ne '') then replace value of node /k:root/k:minx with $minx else (),
    if ($maxx ne '') then replace value of node /k:root/k:maxx with $maxx else ()
}
Badge +10

Hi @dms2, a possible way is to extract the original values from the source XML document as feature attributes (e.g. _original_minx, _original_maxx etc.), merge them to the Update feature, then use them in the expressions. e.g.

if (fme:get-attribute('_minx') ne '') then fme:get-attribute('_minx') else fme:get-attribute('_original_minx')

Alternatively, the XMLXQueryUpdater can also be used more flexibly, if you merge the new values (_minx, _maxx etc.) to the feature which has the XML document. Assuming that the feature has an attribute called "response" which stores this XML document, the following setting is possible.

<?xml version="1.0"?>
<root>
    <minx>0</minx>
    <maxx>100</maxx>
</root>

XQuery Expression:

let $minx := xs:string(fme:get-attribute("_minx"))
let $maxx := xs:string(fme:get-attribute("_maxx"))
return {
    if ($minx ne '') then replace value of node /root/minx with $minx else (),
    if ($maxx ne '') then replace value of node /root/maxx with $maxx else ()
}

0684Q00000ArLPZQA3.png

The first option is perfect. Thank you.

 

 

Reply