Skip to main content
Solved

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

  • April 10, 2018
  • 3 replies
  • 88 views

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

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

This post is closed to further activity.
It may be an old question, an answered question, an implemented idea, or a notification-only post.
Please check post dates before relying on any information in a question or answer.
For follow-up or related questions, please post a new question or idea.
If there is a genuine update to be made, please contact us and request that the post is reopened.

3 replies

takashi
Celebrity
  • 7843 replies
  • 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
Celebrity
  • 7843 replies
  • 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

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
  • 48 replies
  • April 12, 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

The first option is perfect. Thank you.