I have an input string which has csv values. Eg., 1,2,3 I would need to separate each values and assign to target node in for-each loop.
I got this below template that s
Personally, I prefer this variant based on custom extension functions. The method is compact and clean, and works fine in XSLT 1.0 (at least with XALAN 2.7 as embedded in any recent JVM).
1) declare a class with a static method returning a org.w3c.dom.Node
package com.reverseXSL.util;
import org.w3c.dom.*;
import java.util.regex.*;
import javax.xml.parsers.DocumentBuilderFactory;
public class XslTools {
public static Node splitToNodes(String input, String regex) throws Exception {
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element item, list = doc.createElement("List");
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
while (m.find()) {
item = doc.createElement("Item");
StringBuffer sb = new StringBuffer();
for (int i=1; i<=m.groupCount(); ++i) if (m.start(i)>=0) sb.append(m.group(i));
Text txt = doc.createTextNode(sb.toString());
item.appendChild(txt);
list.appendChild(item);
}
return list;
}
}
This function splits an input string on a regex pattern and creates a document fragment of the kind
.
The regex is matched in sequence, each match yielding an Item element whose value is composed from the capturing groups (some possibly empty) inside each regex match. This allows to get rid from delimiters and other syntax chars.
For instance, to split a comma-separated list like " A, B ,, C"
, skip empty values, and trim extra spaces (hence get the above Node list), use a regex like '\s*([^,]+?)\s*(?:,|$)'
- a mind twisting one! If instead you want to split the input text by a fixed size (here 10 chars) with the last Item taking whatever remains, use a regex like '(.{10}|.+)'
- love it!
You can then use the function in XSLT 1.0 as follows (quite compact!):
...
Executed on a template match yielding the input fragment
you'll generate
The trick is not forgetting to follow the function call that generates the Node/Item by the XPath "/Item" (or "/*") as you shall note, so that a Node sequence is returned into the for-each loop.