Skip to main content

Hi there...

 

 

I a list containing adress inforation. The lenght of the list varies from featur to feature so I need a flexible solution... The list looks like this:

 

 

_list{0}.name = "Company 1"

 

_list{0}.zip = "ZIP-Code 1"

 

_list{0}.city = "City 1"

 

_list{1}.name = "Company 2"

 

_list{1}.zip = "ZIP-Code 2"

 

_list{1}.city = "City 2"

 

_list{2}.name = "Company 3"

 

_list{2}.zip = "ZIP-Code 3"

 

_list{2}.city = "City 3"

 

:

 

_list{n}.name = "Company n"

 

_list{n}.zip = "ZIP-Code n"

 

_list{n}.city = "City n"

As you see...the list is of dynamic length... The task is now, to write some of the list elements into attributes:

_list{0}.name => name1

 

_list{0}.city => city1

 

_list{1}.name => name2

 

_list{1}.city => city2

 

_list{2}.name => name3

 

_list{2}.city => city3

 

:

 

_list{n}.name => name_n

 

_list{n}.city => city_n

So I need to create a dynamic number of attributes. I tried the attribute manager, list renamer, list exploder - but not really satisfying. The only way so far is to use the attribute creator but I have no idea how to implement a dynamic number of attributes...

Does anyone has an idea?????

Thanks in advance

Can you tell us why the ListExploder didn't work for you? What would you like the result to look like?

You can also use a combination of the ListElementCounter and a ListIndexer in a looping custom transformer.

If not, there's always Python.


Hi @stefangiese, the BulkAttributeRenamer with these parameters renames every element of the list.

  • Rename: All Attributes

  • Action: Regular Expression Replace

  • Mode: Rename

  • Text To Find: ^_list{(\d+)}\.(.+)$

  • String: \2_\1

However, the transformer renames "_list{0}.xxx" to "xxx_0", i.e. uses 0-based suffix. If you need to use 1-based suffix, a possible way is Python scripting. e.g.

# PythonCaller Script Example: Rename list elements
def processFeature(feature):
    i = 0
    while True:
        name = feature.getAttribute('_list{%d}.name' % i)
        if name == None:
            break
        for item in  'name', 'zip', 'city']:
            feature.performFunction('@RenameAttributes(%s_%d,_list{%d}.%s)' \
                % (item, i+1, i, item))
        i += 1

Note that you will have to expose the new attribute names anyway, if necessary.


Hi @stefangiese, the BulkAttributeRenamer with these parameters renames every element of the list.

  • Rename: All Attributes

  • Action: Regular Expression Replace

  • Mode: Rename

  • Text To Find: ^_list{(\d+)}\.(.+)$

  • String: \2_\1

However, the transformer renames "_list{0}.xxx" to "xxx_0", i.e. uses 0-based suffix. If you need to use 1-based suffix, a possible way is Python scripting. e.g.

# PythonCaller Script Example: Rename list elements
def processFeature(feature):
    i = 0
    while True:
        name = feature.getAttribute('_list{%d}.name' % i)
        if name == None:
            break
        for item in  'name', 'zip', 'city']:
            feature.performFunction('@RenameAttributes(%s_%d,_list{%d}.%s)' \
                % (item, i+1, i, item))
        i += 1

Note that you will have to expose the new attribute names anyway, if necessary.

Hi takashi,

 

BulkAttributeRenamer works fine. The result looks like this:

 

city_0 = <name of city0>

 

city_1 = <name of city1>

 

name_0 = <name of company0>

 

name_1=<name of company1>

 

 

Now I need to write the attributes (city_0, city_1, name_0, name_1...) to my feature (shapefile). I tried the AttributeExploder, but those created attributes (city_0, city_1,...) are not listet in the dropdown menu... 

 

 

Let me try to explain it in a diffirent way... As the result of the Aggregator I have an attribute "city" (and "names") containing a variable number of city names (comma seperated). The attribute lookes like:

 

city = "city1,city2,city3"

 

name = "name1,namea2,name3".

 

Now I want to create for each Element in the attribute a new attribute:

 

city = "city1,city2,city3" turns to:

 

city1="city1"

 

city2="city2"

 

city3="city3"

 

and so on.

 

 

With our hint of the BuldRenamer I am quite close to what I want... Maybe you have an idea to create an individuale attribute out of each element in the attribute "city" (the number is variable)

 

 


Hi @stefangiese, the BulkAttributeRenamer with these parameters renames every element of the list.

  • Rename: All Attributes

  • Action: Regular Expression Replace

  • Mode: Rename

  • Text To Find: ^_list{(\d+)}\.(.+)$

  • String: \2_\1

However, the transformer renames "_list{0}.xxx" to "xxx_0", i.e. uses 0-based suffix. If you need to use 1-based suffix, a possible way is Python scripting. e.g.

# PythonCaller Script Example: Rename list elements
def processFeature(feature):
    i = 0
    while True:
        name = feature.getAttribute('_list{%d}.name' % i)
        if name == None:
            break
        for item in  'name', 'zip', 'city']:
            feature.performFunction('@RenameAttributes(%s_%d,_list{%d}.%s)' \
                % (item, i+1, i, item))
        i += 1

Note that you will have to expose the new attribute names anyway, if necessary.

I'm unclear what the problem is. If the BulkAttributeRenamer created your desired attributes,  I don't think it's necessary to use the AttributeExploder or any other transformers. Just configure the destination Shapefile feature type schema like this.

 

0684Q00000ArMS1QAN.png

 

 


I'm unclear what the problem is. If the BulkAttributeRenamer created your desired attributes, I don't think it's necessary to use the AttributeExploder or any other transformers. Just configure the destination Shapefile feature type schema like this.

 

 

 

The problem is the dynamic number of attributes. Some features will have just city0-city2, some features will have city0-city20.I wanted to avoid to type the possible maximum number of attributes in the resulting schema. I hoped to find a way to create those attributes automatically...

 

 


Probably you will have to add a list attribute called "attribute{}" to the first feature and set dynamic schema parameters in the Shapefile writer feature type appropriately. 

Firstly, see these articles to learn how to configure dynamic schema derived from a schema feature.Even if the number of elements of the "_list{}" were vary depending on each feature, the dynamic schema has to be configured completely when the very first feature input (per destination feature type). A possible solution I can think of is to use a PythonCaller to rename the elements of "_list{}" and also make the first feature as a schema feature.This is a simplified example. Assuming that there is just a single feature type and the destination feature type name is equal to the source feature type name.
# PythonCaller Script Example: Rename elements of "_list{}"
# and add "attribute{}" list to the first feature.
class FeatureProcessor(object):
    def __init__(self):
        self.features = >]
        self.maxCount = 0 # max number of elements of "_list{}"
        
    def input(self, feature):
        names = feature.getAttribute('_list{}.name')
        if names:
            # Rename the elements of "_list{}".
            for i in range(len(names)):
                for item in  'name', 'city']:
                    feature.performFunction('@RenameAttributes(%s_%d,_list{%d}.%s)' \
                        % (item, i, i, item))
                        
            # Update the max number of elements of "_list{}".
            if self.maxCount < len(names):
                self.maxCount = len(names);
                
        # Store the feature.
        self.features.append(feature)
        
    def close(self):
        if self.features:
            # Add "attribute{}" list to the first feature and output it.
            # The first feature will be considered as a schema feature.
            feature = self.featuresÂ0]
            k = 0
            for i in range(self.maxCount):
                for item in f'name', 'city']:
                    feature.setAttribute('attribute{%d}.name' % k, \
                        '%s_%d' % (item, i))
                    feature.setAttribute('attribute{%d}.fme_data_type' % k, \
                        'fme_varchar(50)')
                    k += 1
            self.pyoutput(feature)
            
            # Output 2nd and later features.
            for feature in self.featuresÂ1:]:
                self.pyoutput(feature)

0684Q00000ArKRKQA3.png


Probably you will have to add a list attribute called "attribute{}" to the first feature and set dynamic schema parameters in the Shapefile writer feature type appropriately. 

Firstly, see these articles to learn how to configure dynamic schema derived from a schema feature.Even if the number of elements of the "_list{}" were vary depending on each feature, the dynamic schema has to be configured completely when the very first feature input (per destination feature type). A possible solution I can think of is to use a PythonCaller to rename the elements of "_list{}" and also make the first feature as a schema feature.This is a simplified example. Assuming that there is just a single feature type and the destination feature type name is equal to the source feature type name.
# PythonCaller Script Example: Rename elements of "_list{}"
# and add "attribute{}" list to the first feature.
class FeatureProcessor(object):
    def __init__(self):
        self.features = >]
        self.maxCount = 0 # max number of elements of "_list{}"
        
    def input(self, feature):
        names = feature.getAttribute('_list{}.name')
        if names:
            # Rename the elements of "_list{}".
            for i in range(len(names)):
                for item in  'name', 'city']:
                    feature.performFunction('@RenameAttributes(%s_%d,_list{%d}.%s)' \
                        % (item, i, i, item))
                        
            # Update the max number of elements of "_list{}".
            if self.maxCount < len(names):
                self.maxCount = len(names);
                
        # Store the feature.
        self.features.append(feature)
        
    def close(self):
        if self.features:
            # Add "attribute{}" list to the first feature and output it.
            # The first feature will be considered as a schema feature.
            feature = self.featuresÂ0]
            k = 0
            for i in range(self.maxCount):
                for item in f'name', 'city']:
                    feature.setAttribute('attribute{%d}.name' % k, \
                        '%s_%d' % (item, i))
                    feature.setAttribute('attribute{%d}.fme_data_type' % k, \
                        'fme_varchar(50)')
                    k += 1
            self.pyoutput(feature)
            
            # Output 2nd and later features.
            for feature in self.featuresÂ1:]:
                self.pyoutput(feature)

0684Q00000ArKRKQA3.png

It's also possible to implement without Python scripting.

 

0684Q00000ArMDqQAN.png


Reply