outputValueCalc and dfdl:index()

17 views
Skip to first unread message

Sean Muir

unread,
Dec 7, 2024, 2:07:10 PM12/7/24
to Smooks Users
Per an example I came across to have a counter in the output
<xs:element name="counter" type="xs:int" dfdl:outputValueCalc="{../dfdl:index() + 1}" />
This throws an error on the index()

What I am trying to do is have an incremental counter in the output

not sure that this is something I can do with smooks and dfdl

thanks

Sean


Claude Mamo

unread,
Dec 9, 2024, 3:24:14 AM12/9/24
to smook...@googlegroups.com
Can you point me to the example? dfdl:index() does not exist in the DFDL spec but there's a dfdl:occursIndex(): https://daffodil.apache.org/docs/dfdl/ . It could be that the function is a vendor extension. This would be a good question for the the Daffodil community.

You can increment a counter from a custom Smooks visitor and insert it from within a pipeline. Here's a naive example I wrote:

    <core:smooks filterSourceOn="#document">
        <core:config>
            <smooks-resource-list>
                <core:rewrite>
                    <resource-config selector="record">
                        <resource>org.smooks.examples.pipeline.MyCounter</resource>
                    </resource-config>
                    <core:echo/>
                </core:rewrite>

                <resource-config selector="record">
                    <resource>org.smooks.examples.pipeline.IncrementCounter</resource>
                </resource-config>
               
                <dfdl:unparser schemaUri="my-schema.dfdl.xsd" unparseOnNode="*"/>
            </smooks-resource-list>
        </core:config>
    </core:smooks>

IncrementCounter maintains a counter in Smooks's bean context:

public class IncrementCounter implements BeforeVisitor {
    @Override
    public void visitBefore(Element element, ExecutionContext executionContext) {
        Integer counter = (Integer) executionContext.getBeanContext().getBean("counter");
        if (counter != null) {
            executionContext.getBeanContext().addBean("counter", counter + 1);
        } else {
            executionContext.getBeanContext().addBean("counter", 1);
        }
    }
}


Whereas MyCounter pulls this counter from the bean context and injects it into the stream:

public class MyCounter implements AfterVisitor {
    @Override
    public void visitAfter(Element element, ExecutionContext executionContext) {
        try {
            Stream.out(executionContext).write(XmlUtils.serialize(element) + String.format("<counter>%s</counter>", executionContext.getBeanContext().getBean("counter")));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}


If this a common use case, I reckon we should have an idiomatic way to for inserting counters.

Claude

--
You received this message because you are subscribed to the Google Groups "Smooks Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to smooks-user...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/smooks-user/abc5b8f9-d85b-4442-9161-44e848ef64b3n%40googlegroups.com.

Sean Muir

unread,
Dec 9, 2024, 8:26:42 AM12/9/24
to Smooks Users
We are creating X12 (I am not an expert) and there is a counter feature in one of the segments - I am not sure how prevalent it is in other specs etc 
Thanks for the counter example I will look into using it and will reach out to Daffodil community regarding the index and let you know
Sean

Claude

unread,
Dec 9, 2024, 9:01:36 AM12/9/24
to Smooks Users
Nice. I had built an X12 translator a few years ago so I think you're referring to the header and trailer segments here. You might want to look into FreeMarker (part of Templating cartridge) for rewriting rather than using a custom visitor such as the one I posted in the example. Soon a blog post about Camel + Smooks + X12 will be published on the Apache Camel blog so keep an eye on it. Here's a link to the repo if you're interested: https://github.com/cjmamo/camel-smooks-edi-x12/ . It demonstrates one way to incrementing counters. I'm posting here the diagram from the draft blog post depicting the flow:

edi-x12-camel-smooks.png
Reply all
Reply to author
Forward
0 new messages