BizTalk EDI自定义XSLT嵌套循环输出验证错误求助
这个错误的核心问题很明确:你生成的X12 832(价格/销售目录)文档结构完全不符合EDI X12 00401版本的Schema约束——BizTalk的EDI Schema对元素的层级、顺序和出现规则有极其严格的要求,你把N1Loop1放错位置了。
先搞懂832的核心结构逻辑
X12 00401_832的顶级结构里,X12_00401_832的直接子元素顺序大致是:ISA → GS → ST → LINLoop1(商品行循环) → CTT → SE → GE → IEA
而N1Loop1(名称/地址循环)根本不是X12_00401_832的直接子元素,它应该嵌套在LINLoop1内部(用来标识商品对应的供应商、买家等关联方),或者在特定业务上下文的节点下,绝对不能直接作为根元素的子节点。
你的XSLT问题定位
你当前的循环逻辑大概是这样的:
<xsl:for-each select="customers/customer"> <N1Loop1>...</N1Loop1> <xsl:for-each select="products"> <LINLoop1>...</LINLoop1> </xsl:for-each> </xsl:for-each>
这种写法会把N1Loop1直接塞到X12_00401_832下面,完全违背了832的Schema规则,BizTalk的EDI验证器自然会抛出btm1046错误。
具体解决步骤
调整XSLT的循环嵌套层级
把N1Loop1移动到LINLoop1内部,根据你的业务需求(比如每个商品关联对应客户信息),修改后的XSLT应该是这样的:<!-- 遍历所有商品生成LINLoop1 --> <xsl:for-each select="customers/customer/products"> <LINLoop1> <!-- 在LINLoop1内部嵌套N1Loop1 --> <N1Loop1> <!-- 填充N1段的客户信息 --> <N1> <N101>ST</N101> <N102><xsl:value-of select="../../customerName"/></N102> </N1> </N1Loop1> <!-- 填充LIN段的商品信息 --> <LIN> <LIN01><xsl:value-of select="productId"/></LIN01> <LIN02>UP</LIN02> </LIN> <!-- 其他商品相关段比如CTP、PID等 --> </LINLoop1> </xsl:for-each>用BizTalk映射器内置工具降低错误率
如果你不是必须用纯自定义XSLT,建议用映射器的Loop Functoid来构建循环:先把源的products节点映射到目标的LINLoop1,再把customer节点的字段映射到LINLoop1内部的N1Loop1对应字段,映射器会自动生成符合Schema结构的XSLT,避免手动编写的层级错误。先验证XML结构再做EDI转换
在BizTalk映射器里点击测试映射,查看生成的XML输出,确认N1Loop1是否在LINLoop1内部,而不是直接作为X12_00401_832的子元素。结构没问题后,再进行EDI转换测试。直接参考官方EDI Schema确认结构
你可以在BizTalk安装目录(通常是C:\Program Files (x86)\Microsoft BizTalk Server <版本>\XSD_Schema\EDI)找到X12_00401_832.xsd,用Visual Studio打开查看,明确各个循环和元素的层级关系,从根源上避免结构错误。
内容的提问来源于stack exchange,提问作者Philip

