【问题标题】:Using content from a single XML node as the XML document, while promoting the XML nodes on the same level使用来自单个 XML 节点的内容作为 XML 文档,同时在同一级别上提升 XML 节点
【发布时间】:2018-11-22 10:10:09
【问题描述】:

我正在接收一个 XML 文档,该文档在其节点中包含另一个 XML 文档,如下面的结构所示​​:

<NewTable>
    <conversationID>f5296f48-90b4-4370-8f16-0115a105c161</conversationID>
    <hostUTC>2018-11-20T16:29:36.04Z</hostUTC>
    <msgType>INVOIC</msgType>
    <msgFormat>oioUBL</msgFormat>
    <msgbody>OTHER XML DOCUMENT...</msgbody>
    <fromID>GLN:5790012328619</fromID>
    <toID>KMDoioUBL</toID>
</NewTable>

我考虑过使用信封模式,但在我的情况下,我不能只将标签用作 NewTable 节点的子节点。我不需要 msgbody 标记中 XML 的架构,它应该作为直通发送。我需要的是提升其他一些 XML 节点,例如 msgType,以便它们可以用于过滤 Biztalk 中的文档,同时仅发送 msgbody 标记中的内容。

是否可以在 Biztalk 中使用信封架构来实现这种情况?

【问题讨论】:

    标签: xml schema biztalk envelope


    【解决方案1】:

    我认为这与您的问题有关Extracting XML document in XML node from WCF-SQL message using body path expression

    您可能需要做的第一件事是从任何节点中删除任何 Min Occurs 或 Max Occurs,以便它们仅出现 1。 然后,您可以提升要在消息上下文中保留的属性。

    下一部分是提取 msgbody 部分,在您之前的问题中,答案是使用 XPath 提取适配器中的正文部分,但是在通过 XML 反汇编程序之前您将丢失这些标头,所以而不是您想要创建一个地图来为您提取它。

    只需创建一个将输入和输出设置为您的架构的映射,创建从 msgbody 到 msgbody 的链接。然后右键单击解决方案资源管理器中的地图,然后单击验证地图。这将生成一个 XSLT 文件。将该 XSLT 文件复制到地图的项目目录中,并将其作为现有项目添加到项目中。单击地图的网格并将自定义 XSLT 路径设置为 XSLT。

    从这个问题的示例 XML 文件中,您的 XSLT 看起来像

    <?xml version="1.0" encoding="UTF-16"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var" version="1.0">
      <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
      <xsl:template match="/">
        <xsl:apply-templates select="/NewTable" />
      </xsl:template>
      <xsl:template match="/NewTable">
        <NewTable>
          <msgbody>
            <xsl:value-of select="msgbody/text()" />
          </msgbody>
        </NewTable>
      </xsl:template>
    </xsl:stylesheet>
    

    但由于您只想要正文的值,您需要编辑 XSLT 以删除 &lt;NewTable&gt;&lt;msbody&gt;&lt;/msgbody&gt;&lt;/NewTable&gt; 以及您不想要的任何其他输出节点。

    最后,如果您的 XML 根据您之前的问题进行了转义,您将需要将 disable-output-escaping="yes" 添加到下面的选择中,并按照 How to unescape XML characters with help of XSLT?

    <?xml version="1.0" encoding="UTF-16"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var" version="1.0">
      <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
      <xsl:template match="/">
        <xsl:apply-templates select="/NewTable" />
      </xsl:template>
      <xsl:template match="/NewTable">
            <xsl:value-of select="msgbody/text()" disable-output-escaping="yes"/>
      </xsl:template>
    </xsl:stylesheet>
    

    注意:在 Visual Studio 中测试地图,您必须禁用输出验证,因为它当然与架构不匹配。但是,您可以为该 XML 创建一个模式。

    【讨论】:

    • 是的,它们是相关的 :) 非常感谢您的回答。我已完成所有步骤并将我的架构和映射部署到 Biztalk。我尝试通过将接收管道设置为 XML 接收(并指定我的架构)并将入站映射设置为我之前创建的映射来进行测试,但是执行管道时出现错误:“输入字符串的格式不正确."。当我尝试根据我的架构验证文档时,我没有收到任何错误。这可能是什么原因?
    • 在管道的 XML Dissasembler 阶段是否失败?
    • 我知道为什么会出现错误。我有一个促销活动,将字段从字符串转换为 int。我现在在入站地图上遇到另一个错误,说 msgbody XML 中的命名空间与任何模式都不匹配。如何告诉它忽略 msgbody xml 中的命名空间?
    猜你喜欢
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多