我在入站EDI文件中获取数据,其中一个字段包含我需要从单个字符串中解析的度量。该字段的一个示例是:
11.75x21.25x41.37x
我需要获取第一个X前面的所有值并将它们推送到目标字段(比如长度),第1个和第2个X之间的所有值,并将它们推送到目标字段“width”,并且第二个和第三个x之间的数据,并将其发送到目标字段“高度”。
以下是挑战:这可以仅使用functoid而不是C#代码来完成吗?这是首选,因为如果不需要修改,审查,存储和推送到服务器的代码,客户端修改X之间的数据格式(他们可能会这样做)的管理C#代码更容易维护。
我尝试使用字符串修剪和字符串精确的functoid但它没有用; X之间没有固定的位数,我甚至无法保证总会有小数 - 我最初想要输入的另一个功能。唯一的常数是X.
答案 0 :(得分:0)
是的,你可以只使用functoid来做到这一点 - 但如果你人为地规定你不使用C#(在脚本功能中),那么你就会更加艰难地生活并且不能解决问题你认为你在解决。
您必须使用多个String Find
functoid来挑选该字段的各个部分 - 这只会假设您知道可能提前发生的x
es的数量。将第一个输入作为节点,将第二个输入作为x
进行字符串查找,然后将其连接到String Extract
functoid。要得到第二个,你必须堆叠String Find
functoid,生活变得丑陋。您正在尝试使用BizTalk functoid手动构建递归。
底线是:无论你如何实现这一目标,如果客户端更改了字符串的格式,你必须更改解析逻辑才能将其删除。通过编写一个自定义的functoid(或者只是一个外部的Assembly方法)来管理这个逻辑将更加容易,其核心是:
public string StringPartAt(string s, string sep, int idx)
{
string[] splits = s.Split(sep[0]);
if (splits.Length > idx)
return splits[idx];
return "";
}
这将 更容易维护和理解。你可以在Scripting functoid中设置它并传入你的节点x
和一个从零开始的索引来获取你的字符串,并且只需要将它用于你需要拆分的次数。您甚至可以添加错误处理/日志记录(可能会感谢EventLog中的"Warning: Tried to extract value that was out of range of input"
)。如果您担心客户端使用C#,您也可以用VB或JavaScript编写。即使在自定义XSLT中,它也会更容易(使用substring-before()
几次,或构建一个递归模板),它会比试图破解一堆股票functoid来完成这项任务更好。
这是如何工作的图片(使用内联C#进行演示 - 您可能希望在外部程序集或自定义functoid中使用它以获得可重用性;请注意char
实际上无法使用,您必须使用字符串如上所示):
答案 1 :(得分:0)
事实证明,我们必须为每个值(高度,宽度和长度)使用不同的脚本来从字符串中提取这些值。使用以下C#脚本将每个脚本函数放入脚本函数中,适用于我的地图:
长度:
public decimal getLength(string weights)
{
string[] wgt;
wgt = weights.Split('x');
decimal len = Convert.ToDecimal(wgt[0]);
decimal wid = Convert.ToDecimal(wgt[1]);
decimal hgt = Convert.ToDecimal(wgt[2]);
return len;
}
宽度:
public decimal getWidth(string weights)
{
string[] wgt;
wgt = weights.Split('x');
decimal len = Convert.ToDecimal(wgt[0]);
decimal wid = Convert.ToDecimal(wgt[1]);
decimal hgt = Convert.ToDecimal(wgt[2]);
return wid;
}
高度:
public decimal getHeight(string weights)
{
string[] wgt;
wgt = weights.Split('x');
decimal len = Convert.ToDecimal(wgt[0]);
decimal wid = Convert.ToDecimal(wgt[1]);
decimal hgt = Convert.ToDecimal(wgt[2]);
return hgt;
}