Cameleer

Tokenize language

The tokenize language cuts text into a list of pieces (by a token, a regular expression, a start and end token, or an XML element name), mostly to drive the split EIP.

Name: tokenize · Crate: cameleer-core · Cargo feature: none, always included (build features) · Apache Camel: Tokenize

When to use it

  • Process a file line by line: split with tokenize: "\n".
  • Send records in batches, for example 100 lines per request to an embedding API, with group.
  • Skip a CSV header line with skipFirst.
  • Cut repeated XML elements out of a large document (xml: true) without parsing it as a whole.

Syntax

The expression text, if any, is the name of a header to tokenize; otherwise the body is used. Everything else is set with options. In YAML, tokenize: "," is short for tokenize: {token: ","}.

modeoptionsresult for the input
token (default)token (default ,)text split on the token; a trailing empty piece is dropped
regextoken + regex: truetext split on the regular expression
pairtoken + endToken (+ includeTokens)the text between each start and end token
xmltoken: <item> + xml: trueeach whole <item>...</item> element, nesting aware

group: N joins every N pieces with groupDelimiter (default: the token in token mode, nothing in pair and xml mode). skipFirst: true drops the first piece. \n, \r and \t in token, endToken and groupDelimiter are unescaped. A body that is already a list is passed through (only skipFirst applies).

Examples

Lines in groups, skipping a header

yaml example: tokenize-lines-grouped
- route:
    id: tokenize-lines
    from:
      uri: direct:tokenize-lines
      steps:
        - split:
            tokenize:
              token: "\\n"
              skipFirst: true
              group: 2
            aggregationStrategy: GroupedBodyAggregationStrategy
            steps:
              - setBody:
                  simple: "batch[${body.replace('\n', '|')}]"
text
id,name
1,Ada
2,Grace
3,Linus
text
["batch[1,Ada|2,Grace]","batch[3,Linus]"]

Regular expression

yaml example: tokenize-regex
- route:
    id: tokenize-regex
    from:
      uri: direct:tokenize-regex
      steps:
        - setBody:
            tokenize:
              token: "\\s*[;,]\\s*"
              regex: true
text
red ; green,blue  ,  black
text
["red","green","blue","black"]

Text between start and end tokens

Pull the code blocks out of a model's Markdown answer:

yaml example: tokenize-pair
- route:
    id: tokenize-pair
    from:
      uri: direct:tokenize-pair
      steps:
        - setBody:
            tokenize:
              token: "<sql>"
              endToken: "</sql>"
text
First run <sql>SELECT 1</sql>, then <sql>SELECT 2</sql>.
text
["SELECT 1","SELECT 2"]

XML elements

yaml example: tokenize-xml
- route:
    id: tokenize-xml
    from:
      uri: direct:tokenize-xml
      steps:
        - split:
            tokenize:
              token: "<order>"
              xml: true
            aggregationStrategy: GroupedBodyAggregationStrategy
            steps:
              - setBody:
                  xpath:
                    expression: /order/@id
                    resultType: String
xml
<orders><order id="1"><line/></order><order id="2"/><order id="3">x</order></orders>
text
["1","2","3"]

Tokenize a header

yaml example: tokenize-header
- route:
    id: tokenize-header
    from:
      uri: direct:tokenize-header
      steps:
        - setBody:
            tokenize:
              expression: recipients
              token: ";"
text
ignored
text
["ada@example.com","grace@example.com"]

Options

optiondefaultdescription
token,The separator, regex, start token or element name.
endToken(none)End token: pair mode.
includeTokensfalseIn pair mode, keep the start and end tokens in each piece.
regexfalsetoken is a regular expression.
xmlfalsetoken is an element name (<order> or order); whole elements are returned.
group0Join every N pieces into one.
groupDelimiterthe tokenSeparator used when grouping.
skipFirstfalseDrop the first piece (a header line).
headerName / source(none)Tokenize this header instead of the body.
inheritNamespaceTagNameAccepted and ignored.

Rust DSL

rust
b.from("direct:tokenize-rust")
    .split(tokenize("\n"))
    .to("mock:tokenize-line")
    .end()
    .set_body(tokenize_pair("[", "]", false));

Also tokenize_regex(regex) and tokenize_xml(tag); add group/skipFirst with LanguageOptions::with_option.

Common questions

How do I split a file into lines?

split: {tokenize: "\n"}. Add group: 100 to process 100 lines per exchange, and skipFirst: true to skip a header line.

How do I split a big XML file into records?

tokenize: {token: "<record>", xml: true} returns each <record> element as text, which you can then query with XPath.

Does Cameleer stream the tokens?

No. The tokens of one body are computed as a list, so the whole body is held in memory. This differs from Apache Camel, where tokenize can scan a stream lazily.

Found a problem?

If something on this page doesn't match what Cameleer does, or you hit a bug while building with it, please help fix it, whether you are a person or a coding agent: open an issue that describes what you saw, then fork the repository, fix it, add or update a test, run cargo test --workspace, and open a pull request. CONTRIBUTING.md explains the ground rules.

Edit this page on GitHub