Skip to main content
Question

Update values in xml with conditionals


djmcdermott
Contributor
Forum|alt.badge.img+6

Hi FME'ers,

I am trying to update values in an XML documents but these values are conditional. For example:

IF <MethodCode> like 'FF%' THEN <MethodCode> = 'PM'

and

IF <MethodCode> = 'FF12' AND '<ItemDesc> = 'Basket' THEN <ItemDesc> = 'Wicker Basket'. ELSEIF <MethodCode> = 'FF10' AND '<ItemDesc> = 'Basket' THEN <ItemDesc> = 'Laundry Basket'

I think XQUERY will solve my issue but I don't have time to learn a new query language.

Many thanks,

David

3 replies

takashi
Influencer
  • June 20, 2018

Yes, you can do that with an XQuery expression (XMLXQueryUpdater). I think the following example contains every syntax you have to learn for the present.

Source XML

<items>
    <item>
        <code>X1</code>
        <desc>aaa</desc>
    </item>
    <item>
        <code>X2</code>
        <desc>aaa</desc>
    </item>
    <item>
        <code>X2</code>
        <desc>bbb</desc>
    </item>
    <item>
        <code>Z3</code>
        <desc>aaa</desc>
    </item>
</items>

XQuery Expression (assume that an attribute storing the source XML is set to the XML Attribute parameter in the XMLXQueryUpdater)

for $item in //item
let $code := data($item/code)
let $desc := data($item/desc)
return
if (matches($code'^X.*')) then (
    replace value of node $item/code with 'KK',
    if ($code = 'X1' and $desc = 'aaa'then
        replace value of node $item/desc with 'foo aaa'
    else if ($code ='X2' and $desc = 'aaa'then
        replace value of node $item/desc with 'bar aaa'
    else ()
)
else ()

Result

<items>
    <item>
        <code>KK</code>
        <desc>foo aaa</desc>
    </item>
    <item>
        <code>KK</code>
        <desc>bar aaa</desc>
    </item>
    <item>
        <code>KK</code>
        <desc>bbb</desc>
    </item>
    <item>
        <code>Z3</code>
        <desc>aaa</desc>
    </item>
</items>

If you need more specific solution, please post a small (but valid) sample XML and your desired result corresponding to the sample.


djmcdermott
Contributor
Forum|alt.badge.img+6
  • Author
  • Contributor
  • June 20, 2018
takashi wrote:

Yes, you can do that with an XQuery expression (XMLXQueryUpdater). I think the following example contains every syntax you have to learn for the present.

Source XML

<items>
    <item>
        <code>X1</code>
        <desc>aaa</desc>
    </item>
    <item>
        <code>X2</code>
        <desc>aaa</desc>
    </item>
    <item>
        <code>X2</code>
        <desc>bbb</desc>
    </item>
    <item>
        <code>Z3</code>
        <desc>aaa</desc>
    </item>
</items>

XQuery Expression (assume that an attribute storing the source XML is set to the XML Attribute parameter in the XMLXQueryUpdater)

for $item in //item
let $code := data($item/code)
let $desc := data($item/desc)
return
if (matches($code'^X.*')) then (
    replace value of node $item/code with 'KK',
    if ($code = 'X1' and $desc = 'aaa'then
        replace value of node $item/desc with 'foo aaa'
    else if ($code ='X2' and $desc = 'aaa'then
        replace value of node $item/desc with 'bar aaa'
    else ()
)
else ()

Result

<items>
    <item>
        <code>KK</code>
        <desc>foo aaa</desc>
    </item>
    <item>
        <code>KK</code>
        <desc>bar aaa</desc>
    </item>
    <item>
        <code>KK</code>
        <desc>bbb</desc>
    </item>
    <item>
        <code>Z3</code>
        <desc>aaa</desc>
    </item>
</items>

If you need more specific solution, please post a small (but valid) sample XML and your desired result corresponding to the sample.

Hi @takashi. Thank you for your response. I said to my colleagues after I posted that you’d be the one with the solution. 

 

 

In was very close with my own attempt. Sorry to throw this in but the xml has a namespace. Do I have to declare it and therefore prefix the nodes with //x: (for example)

 


takashi
Influencer
  • June 20, 2018
takashi wrote:

Yes, you can do that with an XQuery expression (XMLXQueryUpdater). I think the following example contains every syntax you have to learn for the present.

Source XML

<items>
    <item>
        <code>X1</code>
        <desc>aaa</desc>
    </item>
    <item>
        <code>X2</code>
        <desc>aaa</desc>
    </item>
    <item>
        <code>X2</code>
        <desc>bbb</desc>
    </item>
    <item>
        <code>Z3</code>
        <desc>aaa</desc>
    </item>
</items>

XQuery Expression (assume that an attribute storing the source XML is set to the XML Attribute parameter in the XMLXQueryUpdater)

for $item in //item
let $code := data($item/code)
let $desc := data($item/desc)
return
if (matches($code'^X.*')) then (
    replace value of node $item/code with 'KK',
    if ($code = 'X1' and $desc = 'aaa'then
        replace value of node $item/desc with 'foo aaa'
    else if ($code ='X2' and $desc = 'aaa'then
        replace value of node $item/desc with 'bar aaa'
    else ()
)
else ()

Result

<items>
    <item>
        <code>KK</code>
        <desc>foo aaa</desc>
    </item>
    <item>
        <code>KK</code>
        <desc>bar aaa</desc>
    </item>
    <item>
        <code>KK</code>
        <desc>bbb</desc>
    </item>
    <item>
        <code>Z3</code>
        <desc>aaa</desc>
    </item>
</items>

If you need more specific solution, please post a small (but valid) sample XML and your desired result corresponding to the sample.

Yes, you have to declare namespaces at the top of the expressions if the source XML has elements belonging to a namespace. General syntax is:
declare namespace <prefix> = "<namespace name>";
Note that a declare statement should end with a semicolon, unlike expression body.

 

Then, in the expression body, qualify all element names belonging to the namespace by the prefix.

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