Skip to main content
Solved

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


dms2
Contributor
Forum|alt.badge.img+11
  • Contributor

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!*)}

Best answer by takashi

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

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

3 replies

takashi
Influencer
  • Best Answer
  • April 10, 2018

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


takashi
Influencer
  • April 10, 2018
takashi wrote:

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 ()
}

dms2
Contributor
Forum|alt.badge.img+11
  • Author
  • Contributor
  • April 12, 2018
takashi wrote:

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.

 

 


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