You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BizTalk发送含动态GUID与数字属性名的JSON方案咨询

我之前在BizTalk项目里碰到过几乎一模一样的动态JSON生成问题,给你几个实际验证过的最优解决方案,帮你优雅搞定这个场景:

最优方案1:采用带属性的规范XML结构(首推)

这是最清晰、最易于维护的方案,核心思路是把原本无效的动态节点名(数字、GUID)转成节点属性,让XML完全符合规范。

第一步:调整XML结构为有效格式

把你提供的无效XML改成如下结构,用name属性存储原本的动态键名:

<root>
  <element>
    <anotherGuid>05060c4c-f0af-46b8-810e-30c0c00a379e</anotherGuid>
    <attr>
      <dynamicEntry name="b587d548-8aa6-42b7-b292-0f3e13452c35">
        <dynamicField name="1">-2.073420455529934786</dynamicField>
      </dynamicEntry>
    </attr>
    <attributes>
      <dynamicAttr name="10">8</dynamicAttr>
      <dynamicAttr name="13">7</dynamicAttr>
      <dynamicAttr name="27">3</dynamicAttr>
      <dynamicAttr name="4">2019-11-05T20:30:57.6Z</dynamicAttr>
      <dynamicAttr name="8">6</dynamicAttr>
    </attributes>
    <guid>80974561-a449-4a94-8b3e-970822b84406</guid>
    <lastModified>2019-11-09T01:44:34.157Z</lastModified>
  </element>
</root>

第二步:自定义管道组件序列化JSON

在管道组件里用Newtonsoft.Json(BizTalk环境建议用稳定的12.x版本,避免兼容性问题)遍历XML节点,把name属性作为JSON的键值:

public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{
    // 读取输入XML
    var xmlStream = pInMsg.BodyPart.GetOriginalDataStream();
    var xmlDoc = new XmlDocument();
    xmlDoc.Load(xmlStream);

    // 构建attr节点的JSON对象
    var dynamicEntry = xmlDoc.SelectSingleNode("//attr/dynamicEntry");
    var attrObj = new JObject();
    var fieldNode = dynamicEntry.SelectSingleNode("dynamicField");
    attrObj[dynamicEntry.Attributes["name"].Value] = new JObject
    {
        [fieldNode.Attributes["name"].Value] = fieldNode.InnerText
    };

    // 构建attributes节点的JSON对象
    var attributesObj = new JObject();
    foreach (XmlNode attrNode in xmlDoc.SelectNodes("//attributes/dynamicAttr"))
    {
        attributesObj[attrNode.Attributes["name"].Value] = attrNode.InnerText;
    }

    // 组合最终JSON
    var finalJson = new JObject
    {
        ["attr"] = attrObj,
        ["guid"] = xmlDoc.SelectSingleNode("//guid").InnerText,
        ["anotherGuid"] = xmlDoc.SelectSingleNode("//anotherGuid").InnerText,
        ["lastModified"] = xmlDoc.SelectSingleNode("//lastModified").InnerText,
        ["attributes"] = attributesObj
    };

    // 将JSON写入输出流
    var jsonStream = new MemoryStream(Encoding.UTF8.GetBytes(finalJson.ToString()));
    pInMsg.BodyPart.Data = jsonStream;
    pInMsg.Context.Promote("MessageType", "http://schemas.microsoft.com/BizTalk/2003/system-properties", "application/json");
    return pInMsg;
}
方案2:前缀替换+XSLT转换

如果不想大幅调整现有XML结构,可以用XSLT给无效节点名加前缀,转成有效XML后再在管道组件里去掉前缀生成JSON。

第一步:用XSLT转换无效XML

编写XSLT脚本,给数字节点加attr_前缀,给GUID节点加guid_前缀:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <!-- 处理数字开头的节点 -->
  <xsl:template match="*[starts-with(local-name(), '1') or starts-with(local-name(), '2') or starts-with(local-name(), '3') or starts-with(local-name(), '4') or starts-with(local-name(), '8')]">
    <xsl:element name="attr_{local-name()}">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

  <!-- 处理GUID格式的节点 -->
  <xsl:template match="*[contains(local-name(), '-')]">
    <xsl:element name="guid_{local-name()}">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

把这个XSLT加到BizTalk映射里,或者作为管道组件的前置步骤。

第二步:管道组件中去除前缀生成JSON

在管道组件序列化时,把节点名的attr_和guid_前缀去掉,作为JSON的键:

// 以attributes节点为例
foreach (XmlNode node in xmlDoc.SelectNodes("//attributes/*"))
{
    var key = node.LocalName.Replace("attr_", "");
    attributesObj[key] = node.InnerText;
}
方案3:BizTalk映射配合自定义XSLT脚本

如果需要在BizTalk映射阶段就完成动态结构的转换,可以用自定义XSLT把动态节点转成键值对列表,再传给管道组件处理。

在BizTalk映射里添加自定义XSLT脚本,把attributes下的动态节点转成<keyValue>结构:

<xsl:for-each select="attributes/*">
  <keyValue>
    <key><xsl:value-of select="local-name()"/></key>
    <value><xsl:value-of select="."/></value>
  </keyValue>
</xsl:for-each>

然后管道组件读取这些<keyValue>节点,遍历生成动态JSON属性。

方案对比与选择
  • 方案1:最推荐,结构规范,序列化逻辑简单,后期维护成本低,完全符合XML和JSON的最佳实践。
  • 方案2:适合现有XML结构改动受限的场景,但需要维护XSLT的节点匹配规则,新增动态键时要更新XSLT。
  • 方案3:适合需要在映射阶段处理业务逻辑的场景,但映射复杂度会提高。

不管选哪个方案,记得把自定义管道组件注册到GAC,并且在BizTalk主机实例中配置好权限,测试时一定要覆盖所有可能的动态键场景。

内容的提问来源于stack exchange,提问作者mburm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:40:34