Skip to main content
Solved

Filter attributes

  • October 16, 2014
  • 8 replies
  • 43 views

Hi all,

 

 

I have a xml file and I am going to check if any of the attributes is empty or not. I was thinking of using "attributeFilter" but this is only applicable for one attribute.

 

Is there any other transformer by which I can choose more than one attribute and check if they are empty (NULL/MISSING/EMPTY)?

 

 

Thank you in advanced

 

Mani

Best answer by takashi

Hi,

 

 

There doesn't seem to be a transformer that exactly fits to your requirement. But the Tester with a test condition like "attr =" (right value is blank) can test whether "attr" is Empty or Null or Missing, since = operator doesn't distinguish the trio. Even though there are 20+ attributes to be tested, I don't think setting 20+ conditions in a Tester is so troublesome.

 

 

If a more flexible way (easier to set/change target attributes) is required, I would create a custom transformer wrapping a simple Tcl script.

 

The implementation would be:

 

- Create a published parameter. Type: Attribute List (space delimited).

 

- Fetch the parameter value - i.e. a string containing space delimited attribute names with a ParameterFetcher to save it  as an attribute. e.g. named "_attrs".

 

- Add a TclCaller to check if one of the attributes contains Empty or Null, or is Missing. This procedure example returns 1 if an attribute is empty or null or missing; otherwise returns 0.

 

-----

 

proc checkEmptyNullMissing {} {

 

    foreach attr [FME_GetAttribute "_attrs"] {

 

        if {[string equal [FME_GetAttribute $attr] {}]} {

 

            return 1

 

        }

 

    }

 

    return 0

 

}

 

-----

 

- Route the feature to different output port according to the result.

 

 

Naturally Python can also do the same thing, but I think Tcl is easier since space delimited attribute names can be treated directly as a list for the iteration.

 

 

One more.

 

If you rename the attributes so that those can be populated into a list using the ListPopulator or the ListExpressionPopulator, you can create a list containing the attribute values, and then the ListSearcher can be used to check if the list contains a specific value.

 

 

Takashi
View original
Did this help you find an answer to your question?
This post is closed to further activity.
It may be a question with a best answer, an implemented idea, or just a post needing no comment.
If you have a follow-up or related question, 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.

8 replies

david_r
Evangelist
  • October 16, 2014
Hi,

 

 

it depends on what you want to accomplish, but there is the NullAttributeMapper that could be helpful in this case.

 

 

David

  • Author
  • October 16, 2014
Thank you for your prompt answer.

 

 

first the problem is I am going to do a validity check based on a set of given values. On of the condition is if the attributes are empty then it should terminate the rest of process. So NullAttributeMapper won't output only the empty attribute.

 

 

Secondly, In general Is there any way to for example see if there is a specific value in a set of attributes(In tester for each attribute it should be written separately and when I wanna check for more than one value(like 20 values) it is time consuming) like the function we have in attributefilter.

 

 

Thank you

 

Mani

takashi
Contributor
Forum|alt.badge.img+19
  • Contributor
  • Best Answer
  • October 17, 2014
Hi,

 

 

There doesn't seem to be a transformer that exactly fits to your requirement. But the Tester with a test condition like "attr =" (right value is blank) can test whether "attr" is Empty or Null or Missing, since = operator doesn't distinguish the trio. Even though there are 20+ attributes to be tested, I don't think setting 20+ conditions in a Tester is so troublesome.

 

 

If a more flexible way (easier to set/change target attributes) is required, I would create a custom transformer wrapping a simple Tcl script.

 

The implementation would be:

 

- Create a published parameter. Type: Attribute List (space delimited).

 

- Fetch the parameter value - i.e. a string containing space delimited attribute names with a ParameterFetcher to save it  as an attribute. e.g. named "_attrs".

 

- Add a TclCaller to check if one of the attributes contains Empty or Null, or is Missing. This procedure example returns 1 if an attribute is empty or null or missing; otherwise returns 0.

 

-----

 

proc checkEmptyNullMissing {} {

 

    foreach attr [FME_GetAttribute "_attrs"] {

 

        if {[string equal [FME_GetAttribute $attr] {}]} {

 

            return 1

 

        }

 

    }

 

    return 0

 

}

 

-----

 

- Route the feature to different output port according to the result.

 

 

Naturally Python can also do the same thing, but I think Tcl is easier since space delimited attribute names can be treated directly as a list for the iteration.

 

 

One more.

 

If you rename the attributes so that those can be populated into a list using the ListPopulator or the ListExpressionPopulator, you can create a list containing the attribute values, and then the ListSearcher can be used to check if the list contains a specific value.

 

 

Takashi

  • Author
  • October 17, 2014

Thank you Takashi.

 

 

The second solution seems really interesting. I've never worked with TcLCaller and don't know about TcL and I really like to know how it works.

I tried to do step by step like what you wrote here but I have problem. Here is what I did in custom transformer:

 

 

1- I created a published parameter (type --> Attribute List (space delimited)) named=FEATURE ATTRIBUTES

 

2- In the next step I add ParameterFetcher give published parameter as Parameter Name and _attrs as Target Attribute.

 

3- In TclCaller in Tcl Expression I put the code you wrote.

 

 

proc checkEmptyNullMissing {} {

 

    for each attr [FME_GetAttribute _attrs] {

 

        if {[string equal [FME_GetAttribute $attr] {}]} {

 

            return 1

 

        }

 

    }

 

    return 0

 

}

 

 

(the rest I don't know how to configure to have the result)

 

 

I have also problem because I have values in integer and not string. Does it have any effect in our case?

 

 

Can you please help me for the rest?

 

 

Best regards,

 

Mani

 

 

takashi
Contributor
Forum|alt.badge.img+19
  • Contributor
  • October 17, 2014
Basically the Tcl interpreter treats every variable as a character string except when performing numeric calculations, so the returned value from a procedure can also be treated as a string, even though the representation is a number. i.e. "0" or "1" in the example.

 

And the returned value will be stored in an attribute which you specified to the "Destination Attribute" parameter of the TclCaller. "_result" by default.

 

So you can test the value ("0" or "1") with a Tester.

 

 

See also here to learn more about the TclCaller.

 

TclCaller help (http://docs.safe.com/fme/html/FME_Transformers/Default.htm#Transformers/tclcaller.htm)

 


takashi
Contributor
Forum|alt.badge.img+19
  • Contributor
  • October 17, 2014
"foreach" is a Tcl command, you can not separate "for" and "each".

takashi
Contributor
Forum|alt.badge.img+19
  • Contributor
  • October 17, 2014
It's maybe unnecessary addition... don't forget to set the procedure name - "checkEmptyNullMissing" to the "Tcl Expression" parameter of the TclCaller.

  • Author
  • October 17, 2014
Thank you so much. It works perfectly :)

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