Skip to main content

Hi,

 

I am in need to convert an attribute with “188-195” as value (Wich means 188

up to and including

195) in “188;189;190;191;192;193;194;195”.

How can this be done in FME workbench 2024.1.0.0.

With a  combination of transformers AttributeCreator, AtributeSplitter, ListElementCounter, ListExploder and AttributeManager I am be able to produce the 8 new features.

 

THNX.

Multiple ways to do this.

Pure FME:

  • AttributeSplitter to split the values to a list.
  • ListExploder to create features from the list.

  • StatisticsCalculator to calculate the minimum value and the range.

  • Cloner to create a feature for each position in the range.

  • AttributeCreator to calculate the value for each feature using min value and copynum

  • Aggregator to merge all features and concatenate the string.

Python:

  • PythonCaller with

import fme
import fmeobjects

class FeatureProcessor(object):

    def input(self, feature: fmeobjects.FMEFeature):
        
        # Get the input from an attribute.
        input_string = feature.getAttribute('input')

        # Split the input string to get the start and end of the range.
        start, end = map(int, input_string.split('-'))

        # Generate the range and join with semicolons.
        output_string = ';'.join(str(i) for i in range(start, end + 1))

        # Write the result to an attribute.
        feature.setAttribute('output',output_string)
        self.pyoutput(feature)

 

Sample workspace attached.


This should do the trick:

  • ExpressionEvaluator to get the numbers of digits
  • Cloner to create a feature for each digit
  • Another ExpressionEvaluator to add the cloner copy number to the first range number
  • Finally an Aggregator to combine all the values

 


Personally I would use a Cloner based solution similar to @dustin’s solution for ease of implementation and self-documentation, but a speedy alternative solution that uses less Transformers is to use SQL Recursion inside the SQLite based InlineQuerier

It is sort of in-between using just out-of-the-box Transformers and having to go full programmatic mode in Python (which can bring its own debugging issues)

 

SQL Statement in the sample InlineQuerier below is

 

WITH RECURSIVE

--Common-Table-Expression that extracts the Left and Right Numbers arounda "-" character

ValueRange(ID, MinNumber, MaxNumber) AS
(
SELECT
ID
,0+(trim(substr("test_attr",0,instr("test_attr","-")))) AS MinNumber
,0+(trim(substr("test_attr",instr("test_attr","-")+1))) AS MaxNumber
FROM "Output"
)

--CTE that initially selects a single row with the dervied Minimum and Maximum Numbers
--and then keeps attempting to add new rows with a List Value = to the Previous Row List Value + 1 until reach MaxNumber
--As safety mechanism to prevent infinite looping, hard code an upper trial limit of 10,000 new values

,ClonedValues(ID,MinNumber,MaxNumber,ElementID,ListValue) AS
(
SELECT ID, MinNumber, MaxNumber, 1, MinNumber FROM ValueRange
UNION ALL SELECT ID, MinNumber, MaxNumber, ElementID+1, ListValue+1 FROM ClonedValues WHERE ListValue<MaxNumber AND ElementID<10000
)

--Select all Values from the CTE--

SELECT * FROM ClonedValues


 



Input

 

Output

 


Reply