Andrey Davydenko
Andrey Davydenko

Reputation: 350

Multiple launch iterator functoid in Biztalk mapping

The source file has an identifying value in the field name.

<?xml version="1.0"?>
<root>
    <line>
        <name>Test1</name>
        <data>data1</data>
    </line>
    <line>
        <name>Test1</name>
        <data>data2</data>
    </line>
    <line>
        <name>Test2</name>
        <data>data3</data>
    </line>
    <line>
        <name>Test1</name>
        <data>data4</data>
    </line>
</root>

If I use the iterator functoid in the straight way, I get such result:

Biztalk Mapping

<?xml version="1.0"?>
<root>
    <line>
        <sequence>1</sequence>
        <name>Test1</name>
        <data>data1</data>
    </line>
    <line>
        <sequence>2</sequence>
        <name>Test1</name>
        <data>data2</data>
    </line>
    <line>
        <sequence>3</sequence>
        <name>Test2</name>
        <data>data3</data>
    </line>
    <line>
        <sequence>4</sequence>
        <name>Test1</name>
        <data>data4</data>
    </line>
</root>

How can I fill the sequence field, if it starts from 1 for every new value in the field name and continues sequence from the last value if it meets any occured value? I expected such result in the output file:

<?xml version="1.0"?>
<root>
    <line>
        <sequence>1</sequence>
        <name>Test1</name>
        <data>data1</data>
    </line>
    <line>
        <sequence>2</sequence>
        <name>Test1</name>
        <data>data2</data>
    </line>
    <line>
        <sequence>1</sequence>
        <name>Test2</name>
        <data>data3</data>
    </line>
    <line>
        <sequence>3</sequence>
        <name>Test1</name>
        <data>data4</data>
    </line>
</root>

Upvotes: 2

Views: 157

Answers (1)

Dan Field
Dan Field

Reputation: 21651

The iterator functoid gets the iteration of the current node - it doesn't look at the text at all. To achieve what you're trying to do, it'd probably be easiest to use a C# Scripting functoid (which would replace your current iterator functoid) and a Dictionary<string, int> to track how many times you've seen a particular name; this would be the contents of the functoid:

System.Collections.Generic.Dictionary<string, int> tracker = new System.Collections.Generic.Dictionary<string, int>();

public string GetNameCount(string name)
{
    int ct;
    if (tracker.TryGetValue(name, out ct))
    {
        ct++;
        tracker[name] = ct;
        return ct.ToString();
    }
    else
    {
        tracker.Add(name, 1);
        return "1";
    }
}

Might be a good idea to put it in an external assembly if you'll use it in more than one map (or just for debugging/maintenance purposes).

Doing this in pure XSLT would require some kind of grouping/counting that would likely be far less efficient.

Upvotes: 1

Related Questions